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 ()
{
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)
{
}
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>
/// </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));
}
iparams = new ReflectionParameters (mb);
// Is property
- if (mb.IsSpecialName && iparams.Count == 0)
+ if (mb.IsSpecialName && iparams.Count == 0 && !mb.IsConstructor)
return GetFullNameSignature (mb);
for (int i = 0; i < iparams.Count; i++) {
sig.Append (")");
// Is indexer
- if (mb.IsSpecialName && iparams.Count == 1) {
+ if (mb.IsSpecialName && iparams.Count == 1 && !mb.IsConstructor) {
sig.Replace ('(', '[');
sig.Replace (')', ']');
}
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.
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)
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 tparam.IsSubclassOf (parent);
+ }
+
do {
if (IsEqualGenericInstance (type, parent))
return true;
//
// 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 (IsSubclassOf (type, parent))
+ if (IsFamilyAccessible (type, parent))
return true;
// Handle nested types.
/// 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)
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;
/// </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) {
- TypeContainer 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 declare_local_method = null;
if (ma == MethodAttributes.Private)
return private_ok ||
- IsEqual (invocation_type, mb.DeclaringType) ||
+ IsPrivateAccessible (invocation_type, mb.DeclaringType) ||
IsNestedChildOf (invocation_type, mb.DeclaringType);
//
if (invocation_type == null)
return false;
- if (!IsSubclassOrNestedChildOf (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 && (qualifier_type != null) &&
!IsEqualGenericInstance (invocation_type, qualifier_type) &&
- TypeManager.IsSubclassOf (invocation_type, qualifier_type) &&
+ TypeManager.IsFamilyAccessible (invocation_type, qualifier_type) &&
!TypeManager.IsNestedChildOf (invocation_type, qualifier_type))
return false;
if (fa == FieldAttributes.Private)
return private_ok ||
- IsEqual (invocation_type, fi.DeclaringType) ||
+ IsPrivateAccessible (invocation_type, fi.DeclaringType) ||
IsNestedChildOf (invocation_type, fi.DeclaringType);
//
if (invocation_type == null)
return false;
- if (!IsSubclassOrNestedChildOf (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 && (qualifier_type != null) &&
!IsEqualGenericInstance (invocation_type, qualifier_type) &&
- TypeManager.IsSubclassOf (invocation_type, qualifier_type) &&
+ TypeManager.IsFamilyAccessible (invocation_type, qualifier_type) &&
!TypeManager.IsNestedChildOf (invocation_type, qualifier_type))
return false;
if (((qualifier_type == null) || (qualifier_type == invocation_type)) &&
(invocation_type != null) &&
- IsEqual (m.DeclaringType, invocation_type))
+ IsPrivateAccessible (m.DeclaringType, invocation_type))
return true;
//
static Closure closure = new Closure ();
static MemberFilter FilterWithClosure_delegate = new MemberFilter (closure.Filter);
- static MemberFilter FilterNone_delegate = new MemberFilter (FilterNone);
//
// Looks up a member called `name' in the `queried_type'. This lookup
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;
}