2003-05-27 Miguel de Icaza <miguel@ximian.com>
[mono.git] / mcs / mcs / decl.cs
index 1e3fea121644cdff19f0c1c1876aec4efb654e4c..e293e0ad5a975543950a4bd67e4b065e7912c422 100755 (executable)
@@ -297,9 +297,9 @@ namespace Mono.CSharp {
                ///   Returns a status code based purely on the name
                ///   of the member being added
                /// </summary>
-               protected AdditionResult IsValid (string name)
+               protected AdditionResult IsValid (string basename, string name)
                {
-                       if (name == Basename)
+                       if (basename == Basename)
                                return AdditionResult.EnclosingClash;
 
                        if (defined_names.Contains (name))
@@ -454,9 +454,10 @@ namespace Mono.CSharp {
                        if (type_resolve_ec == null)
                                type_resolve_ec = GetTypeResolveEmitContext (parent, loc);
                        type_resolve_ec.loc = loc;
+                       type_resolve_ec.ContainerType = TypeBuilder;
 
                        int errors = Report.Errors;
-                       Expression d = e.Resolve (type_resolve_ec, ResolveFlags.Type);
+                       Expression d = e.ResolveAsTypeTerminal (type_resolve_ec);
                        
                        if (d == null || d.eclass != ExprClass.Type){
                                if (!silent && errors == Report.Errors){
@@ -466,7 +467,7 @@ namespace Mono.CSharp {
                        }
 
                        if (!CheckAccessLevel (d.Type)) {
-                               Report. Error (122, "`" + d.Type + "' " +
+                               Report. Error (122, loc,  "`" + d.Type + "' " +
                                       "is inaccessible because of its protection level");
                                return null;
                        }
@@ -482,8 +483,10 @@ namespace Mono.CSharp {
                {
                        if (type_resolve_ec == null)
                                type_resolve_ec = GetTypeResolveEmitContext (parent, loc);
+                       type_resolve_ec.loc = loc;
+                       type_resolve_ec.ContainerType = TypeBuilder;
 
-                       Expression d = e.Resolve (type_resolve_ec, ResolveFlags.Type);
+                       Expression d = e.ResolveAsTypeTerminal (type_resolve_ec);
                         
                        if (d == null || d.eclass != ExprClass.Type){
                                if (!silent){
@@ -495,14 +498,52 @@ namespace Mono.CSharp {
                        return d;
                }
                
-               bool CheckAccessLevel (Type check_type) 
+               public bool CheckAccessLevel (Type check_type) 
                {
-                       if (check_type.IsPublic || check_type.IsNestedPublic)
+                       if (check_type == TypeBuilder)
+                               return true;
+                       
+                       TypeAttributes check_attr = check_type.Attributes & TypeAttributes.VisibilityMask;
+                       
+                       //
+                       // Broken Microsoft runtime, return public for arrays, no matter what 
+                       // the accessibility is for their underlying class, and they return 
+                       // NonPublic visibility for pointers
+                       //
+                       if (check_type.IsArray || check_type.IsPointer)
+                               return CheckAccessLevel (check_type.GetElementType ());
+
+                       if (check_attr == TypeAttributes.Public)
                                return true;
                        
-                       if (check_type.Assembly == TypeBuilder.Assembly)
+                       if (check_attr == TypeAttributes.NestedPublic)
                                return true;
 
+                       if (check_attr == TypeAttributes.NestedPrivate){
+                               string check_type_name = check_type.FullName;
+                               string type_name = TypeBuilder.FullName;
+                               
+                               int cio = check_type_name.LastIndexOf ("+");
+                               string container = check_type_name.Substring (0, cio);
+
+                               //
+                               // Check if the check_type is a nested class of the current type
+                               //
+                               if (check_type_name.StartsWith (type_name + "+")){
+                                       return true;
+                               }
+                               
+                               if (type_name.StartsWith (container)){
+                                       return true;
+                               }
+
+                               return false;
+                       }
+                       
+                       if (check_type.Assembly == TypeBuilder.Assembly){
+                               return true;
+                       }
+
                        return false;
 
                }
@@ -514,8 +555,9 @@ namespace Mono.CSharp {
                        Type t;
 
                        error = false;
+
                        name = MakeFQN (ns, name);
-                       
+
                        t  = TypeManager.LookupType (name);
                        if (t != null)
                                return t;
@@ -585,7 +627,6 @@ namespace Mono.CSharp {
                        // Attempt to lookup the class on our namespace and all it's implicit parents
                        //
                        for (string ns = Namespace.Name; ns != null; ns = RootContext.ImplicitParent (ns)) {
-
                                t = LookupInterfaceOrClass (ns, name, out error);
                                if (error)
                                        return null;
@@ -639,7 +680,6 @@ namespace Mono.CSharp {
                                                }
                                                
                                                t = match;
-                                               ue.Used = true;
                                        }
                                }
                                if (t != null)
@@ -1247,6 +1287,7 @@ namespace Mono.CSharp {
                        // If this is a method-only search, we try to use the method cache if
                        // possible; a lookup in the method cache will return a MemberInfo with
                        // the correct ReflectedType for inherited methods.
+                       
                        if (method_search && (method_hash != null))
                                applicable = (ArrayList) method_hash [name];
                        else
@@ -1305,8 +1346,9 @@ namespace Mono.CSharp {
                        // search, we restart in method-only search mode if the first match is
                        // a method.  This ensures that we return a MemberInfo with the correct
                        // ReflectedType for inherited methods.
-                       if (do_method_search && (list.Count > 0))
+                       if (do_method_search && (list.Count > 0)){
                                return FindMembers (MemberTypes.Method, bf, name, filter, criteria);
+                       }
 
                        return new MemberList (list);
                }