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 exception_type;
static public Type activator_type;
static public Type invalid_operation_exception_type;
+ static public Type not_supported_exception_type;
static public Type obsolete_attribute_type;
- static public object conditional_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 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 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
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;
// <remarks>
// Holds the Array of Assemblies that have been loaded
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 ()
types.Add (name, t);
}
- public static void AddUserType (string name, TypeBuilder t, TypeExpr[] ifaces)
+ public static void AddUserType (string name, TypeBuilder t)
{
try {
types.Add (name, t);
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, TypeExpr [] 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, TypeExpr [] 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)
builder_to_declspace.Add (t, en);
}
- public static void AddUserInterface (string name, TypeBuilder t, Interface i, TypeExpr [] ifaces)
- {
- AddUserType (name, t, ifaces);
- builder_to_declspace.Add (t, i);
- }
-
public static void AddMethod (MethodBase builder, IMethodData method)
{
builder_to_method.Add (builder, method);
return (IMethodData) builder_to_method [builder];
}
- public static void AddTypeParameter (Type t, TypeParameter tparam, TypeExpr[] ifaces)
+ public static void AddTypeParameter (Type t, TypeParameter tparam)
{
- if (!builder_to_type_param.Contains (t)) {
+ if (!builder_to_type_param.Contains (t))
builder_to_type_param.Add (t, tparam);
-
- if (ifaces != null)
- builder_to_ifaces [t] = ifaces;
- }
}
/// <summary>
{
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)
{
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)
}
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.HasConstructorConstraint;
- else {
- object[] attrs = t.GetCustomAttributes (
- TypeManager.new_constraint_attr_type, false);
+ return tparam.GenericConstraints;
- return attrs.Length > 0;
- }
+ return new ReflectionConstraints (t);
}
/// <summary>
assemblies = n;
}
+ public static Assembly [] GetAssemblies ()
+ {
+ return assemblies;
+ }
+
/// <summary>
/// Registers a module builder to lookup types from
/// </summary>
if (t != null)
return t;
- if (negative_hits.Contains (name))
- return null;
-
t = LookupTypeReflection (name);
-
if (t == null)
- negative_hits [name] = null;
- else
+ return null;
+
types [name] = t;
-
return t;
}
/// </summary>
public static void LoadAllImportedTypes ()
{
- if (!CodeGen.Assembly.IsClsCompliant)
- return;
-
all_imported_types = new Hashtable ();
foreach (Assembly a in assemblies) {
foreach (Type t in a.GetExportedTypes ()) {
@"^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));
}
/// </summary>
static public string GetFullNameSignature (MemberInfo mi)
{
- string n = mi.Name;
- if (n == ".ctor")
- n = mi.DeclaringType.Name;
+ return mi.DeclaringType.FullName.Replace ('+', '.') + '.' + mi.Name;
+ }
- return mi.DeclaringType.FullName.Replace ('+', '.') + '.' + n;
+ 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)
/// </summary>
static public string CSharpSignature (MethodBase mb)
{
- string sig = "(";
+ StringBuilder sig = new StringBuilder ("(");
//
// FIXME: We should really have a single function to do
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 (")");
- return GetFullNameSignature (mb) + sig;
+ // Is indexer
+ if (mb.IsSpecialName && iparams.Count == 1 && !mb.IsConstructor) {
+ sig.Replace ('(', '[');
+ sig.Replace (')', ']');
+ }
+
+ return GetFullNameSignature (mb) + sig.ToString ();
}
/// <summary>
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");
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
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.
//
unverifiable_code_ctor = GetConstructor (
unverifiable_code_type, void_arg);
+ default_member_ctor = GetConstructor (default_member_type, string_);
+
//
// InvalidOperationException
//
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.
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;
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;
+
+ return tc.Kind == Kind.Interface;
}
- public static bool IsEqualGenericType (Type a, Type b)
+ public static bool IsEqual (Type a, Type b)
{
+ if (a.Equals (b))
+ return true;
+
if ((a is TypeBuilder) && a.IsGenericTypeDefinition && b.IsGenericInstance) {
//
// `a' is a generic type definition's TypeBuilder and `b' is a
// The first argument of `Test' will be the generic instance
// "Stack<!0>" - 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;
return false;
for (int i = 0; i < aparams.Length; i++)
- if (!aparams [i].Equals (bparams [i]))
+ if (!IsEqual (aparams [i], bparams [i]))
return false;
return true;
}
- return false;
- }
+ if (a.IsGenericParameter && b.IsGenericParameter) {
+ if ((a.DeclaringMethod == null) || (b.DeclaringMethod == null))
+ return false;
+ return a.GenericParameterPosition == b.GenericParameterPosition;
+ }
+
+ if (a.IsArray && b.IsArray) {
+ if (a.GetArrayRank () != b.GetArrayRank ())
+ return false;
+ return IsEqual (a.GetElementType (), b.GetElementType ());
+ }
+
+ if (a.IsGenericInstance && b.IsGenericInstance) {
+ Type at = a.GetGenericTypeDefinition ();
+ Type bt = b.GetGenericTypeDefinition ();
+
+ if (a.GetGenericTypeDefinition () != b.GetGenericTypeDefinition ())
+ return false;
+
+ Type[] aargs = a.GetGenericArguments ();
+ Type[] bargs = b.GetGenericArguments ();
+
+ if (aargs.Length != bargs.Length)
+ return false;
+
+ for (int i = 0; i < aargs.Length; i++) {
+ if (!IsEqual (aargs [i], bargs [i]))
+ return false;
+ }
- public static bool IsEqual (Type a, Type b)
- {
- if (a.Equals (b))
return true;
- else
- return IsEqualGenericType (a, b);
+ }
+
+ return false;
}
public static bool MayBecomeEqualGenericTypes (Type a, Type b)
return false;
}
- public static bool IsSubclassOf (Type type, Type parent)
+ public static bool IsEqualGenericInstance (Type type, Type parent)
{
- if (type.IsGenericInstance && !parent.IsGenericInstance)
+ 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<T>
+ // {
+ // void Test (Stack<T> stack) { }
+ // }
+ //
+ // The first argument of `Test' will be the generic instance
+ // "Stack<!0>" - 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 type.IsSubclassOf (parent);
+ 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 IsSubclassOrNestedChildOf (Type type, Type parent)
+ public static bool IsNestedFamilyAccessible (Type type, Type parent)
{
do {
- if ((type == parent) || type.IsSubclassOf (parent) ||
- IsEqualGenericType (type, parent))
+ if (IsFamilyAccessible (type, parent))
return true;
// Handle nested types.
//
public static bool IsNestedChildOf (Type type, Type parent)
{
- if (type == parent)
+ if (IsEqual (type, parent))
return false;
type = type.DeclaringType;
while (type != null) {
- if (type == parent)
+ if (IsEqual (type, parent))
return true;
type = type.DeclaringType;
/// 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 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)
/// </summary>
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;
}
- }
/// <summary>
/// Returns the argument types for an indexer based on its PropertyInfo
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)
Pair pair = (Pair) events [ei];
return (MethodInfo) pair.First;
- } else
- return ei.GetAddMethod ();
+ }
+ return ei.GetAddMethod (true);
}
static public MethodInfo GetRemoveMethod (EventInfo ei)
Pair pair = (Pair) events [ei];
return (MethodInfo) pair.Second;
- } else
- return ei.GetRemoveMethod ();
+ }
+ return ei.GetRemoveMethod (true);
}
static Hashtable priv_fields_events;
public static bool CheckStructCycles (TypeContainer tc, Hashtable seen,
Hashtable hash)
{
- if (!(tc is Struct) || IsBuiltinType (tc))
+ if ((tc.Kind != Kind.Struct) || IsBuiltinType (tc))
return true;
//
/// This expands in context like: IA; IB : IA; IC : IA, IB; the interface "IC" to
/// be IA, IB, IC.
/// </remarks>
- public static TypeExpr[] ExpandInterfaces (TypeExpr [] base_interfaces)
+ public static Type[] ExpandInterfaces (EmitContext ec, TypeExpr [] base_interfaces)
{
ArrayList new_ifaces = new ArrayList ();
foreach (TypeExpr iface in base_interfaces){
- if (!new_ifaces.Contains (iface))
- new_ifaces.Add (iface);
+ Type itype = iface.ResolveType (ec);
+ if (itype == null)
+ return null;
+
+ if (!new_ifaces.Contains (itype))
+ new_ifaces.Add (itype);
- TypeExpr [] implementing = iface.GetInterfaces ();
+ Type [] implementing = itype.GetInterfaces ();
- foreach (TypeExpr imp in implementing){
+ foreach (Type imp in implementing){
if (!new_ifaces.Contains (imp))
new_ifaces.Add (imp);
}
}
- TypeExpr [] ret = new TypeExpr [new_ifaces.Count];
+ Type [] ret = new Type [new_ifaces.Count];
new_ifaces.CopyTo (ret, 0);
return ret;
}
/// This function returns the interfaces in the type `t'. Works with
/// both types and TypeBuilders.
/// </summary>
- public static TypeExpr [] GetInterfaces (Type t)
+ public static Type [] GetInterfaces (Type t)
{
- TypeExpr [] cached = iface_cache [t] as TypeExpr [];
+ Type [] cached = iface_cache [t] as Type [];
if (cached != null)
return cached;
t = TypeManager.array_type;
if (t is TypeBuilder){
- TypeExpr [] parent_ifaces;
+ Type[] parent_ifaces;
if (t.BaseType == null)
- parent_ifaces = NoTypeExprs;
+ parent_ifaces = NoTypes;
else
parent_ifaces = GetInterfaces (t.BaseType);
- TypeExpr [] type_ifaces = (TypeExpr []) builder_to_ifaces [t];
+ Type[] type_ifaces = (Type []) builder_to_ifaces [t];
if (type_ifaces == null)
- type_ifaces = NoTypeExprs;
+ type_ifaces = NoTypes;
int parent_count = parent_ifaces.Length;
- TypeExpr [] result = new TypeExpr [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 if (t is GenericTypeParameterBuilder){
- TypeExpr[] type_ifaces = (TypeExpr []) builder_to_ifaces [t];
+ Type[] type_ifaces = (Type []) builder_to_ifaces [t];
if (type_ifaces == null)
- type_ifaces = NoTypeExprs;
+ type_ifaces = NoTypes;
iface_cache [t] = type_ifaces;
return type_ifaces;
} else {
- Type [] ifaces = t.GetInterfaces ();
- if (ifaces.Length == 0)
- return NoTypeExprs;
-
- TypeExpr [] result = new TypeExpr [ifaces.Length];
- for (int i = 0; i < ifaces.Length; i++)
- result [i] = new TypeExpression (ifaces [i], Location.Null);
-
- iface_cache [t] = result;
- return result;
+ Type[] ifaces = t.GetInterfaces ();
+ iface_cache [t] = ifaces;
+ return ifaces;
}
}
//
// gets the interfaces that are declared explicitly on t
//
- public static TypeExpr [] GetExplicitInterfaces (TypeBuilder t)
+ public static Type [] GetExplicitInterfaces (TypeBuilder t)
{
- return (TypeExpr []) builder_to_ifaces [t];
+ return (Type []) builder_to_ifaces [t];
}
/// <remarks>
/// </remarks>
public static bool ImplementsInterface (Type t, Type iface)
{
- TypeExpr [] interfaces;
+ Type [] interfaces;
//
// FIXME OPTIMIZATION:
interfaces = GetInterfaces (t);
if (interfaces != null){
- foreach (TypeExpr i in interfaces){
- if (i.Type == iface)
+ foreach (Type i in interfaces){
+ if (i == iface)
return true;
}
}
/// </summary>
/// <remarks>
/// 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'
/// </remarks>
t = t.GetGenericTypeDefinition ();
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";
-
- return tc.IndexerName;
- }
+ TypeContainer tc = t.IsInterface ? LookupInterface (t) : LookupTypeContainer (t);
+ return tc == null ? TypeContainer.DefaultIndexerName : tc.IndexerName;
}
System.Attribute attr = System.Attribute.GetCustomAttribute (
return dma.MemberName;
}
- return "Item";
+ return TypeContainer.DefaultIndexerName;
}
- static MethodInfo pinned_method = null;
- public static void MakePinned (LocalBuilder builder)
- {
- if (pinned_method == null) {
- pinned_method = typeof (LocalBuilder).GetMethod ("MakePinned", BindingFlags.Instance | BindingFlags.NonPublic);
- if (pinned_method == null) {
- Report.Warning (-24, new Location (-1), "Microsoft.NET does not support making pinned variables." +
+ 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;
+ return ig.DeclareLocal (t);
}
}
-
- pinned_method.Invoke (builder, null);
+ return (LocalBuilder) declare_local_method.Invoke (ig, new object [] { t, true });
}
-
//
// Returns whether the array of memberinfos contains the given method
//
return target_list;
}
- [Flags]
- public enum MethodFlags {
- ShouldIgnore = 1 << 2
- }
-
static public bool IsGenericMethod (MethodBase mb)
{
if (mb.DeclaringType is TypeBuilder) {
return mb.IsGenericMethodDefinition;
}
- //
- // 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)
- {
- MethodFlags flags = 0;
-
- if (mb.Mono_IsInflatedMethod)
- mb = mb.GetGenericMethodDefinition ();
-
- if (mb.DeclaringType is TypeBuilder){
- IMethodData method = (IMethodData) builder_to_method [mb];
- if (method == null) {
- // FIXME: implement Obsolete attribute on Property,
- // Indexer and Event.
- return 0;
- }
-
- if (method.ShouldIgnore ())
- flags |= MethodFlags.ShouldIgnore;
-
- return flags;
- }
-
- 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;
-
- //
- // Skip over conditional code.
- //
- if (a.TypeId == TypeManager.conditional_attribute_type){
- ConditionalAttribute ca = (ConditionalAttribute) a;
-
- if (RootContext.AllDefines [ca.ConditionString] == null)
- flags |= MethodFlags.ShouldIgnore;
- }
- }
-
- return flags;
- }
-
#region MemberLookup implementation
//
// 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_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)) &&
- (closure_invocation_type != null) && IsEqual (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 ||
- IsEqual (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;
}
// 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) &&
- !TypeManager.IsNestedChildOf (closure_invocation_type, 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;
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 ||
- IsEqual (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;
}
// 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) &&
- !TypeManager.IsNestedChildOf (closure_invocation_type, 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;
// 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
// 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)
+ 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);
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;
bool skip_iface_check = true, used_cache = false;
bool always_ok_flag = false;
- 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
else
bf = original_bf;
- closure_private_ok = (original_bf & BindingFlags.NonPublic) != 0;
+ closure.private_ok = (original_bf & BindingFlags.NonPublic) != 0;
Timer.StopTimer (TimerType.MemberLookup);
if (queried_type.IsArray)
queried_type = TypeManager.array_type;
- TypeExpr [] ifaces = GetInterfaces (queried_type);
+ Type [] ifaces = GetInterfaces (queried_type);
if (ifaces == null)
return null;
- foreach (TypeExpr itype in ifaces){
+ foreach (Type itype in ifaces){
MemberInfo [] x;
- x = MemberLookup (null, null, itype.Type, mt, bf, name);
+ x = MemberLookup (null, null, itype, mt, bf, name, null);
if (x != null)
return x;
}
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);
-
- foreach (MethodInfo m in methods){
- if (m == mb)
- return true;
- }
- } else if (mi is MyEventBuilder){
- Pair p = (Pair) events [mi];
-
- 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;
+ string name = mb.Name;
+ if (name.StartsWith ("get_") || name.StartsWith ("set_"))
+ return mb.DeclaringType.GetProperty (name.Substring (4)) != null;
- if (ei.GetRaiseMethod (true) == mb)
- return true;
- }
- }
+ if (name.StartsWith ("add_"))
+ return mb.DeclaringType.GetEvent (name.Substring (4)) != null;
- //
- // Now check if it is an operator method
- //
- string s = mb.Name;
+ if (name.StartsWith ("remove_"))
+ return mb.DeclaringType.GetEvent (name.Substring (7)) != null;
- 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;
}
}
}
- public IMemberContainer Parent {
+ public IMemberContainer ParentContainer {
get {
return BaseType;
}