X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fgmcs%2Fnamespace.cs;h=ec0a8347be7f965ea04df864df213b262a8c2377;hb=cffda3181a45b81bbf989a128da6f7a5047a6a99;hp=11c5a7ec736053e066a75455da764b9949e81fb4;hpb=60f7123e13303e1c32f4b916f5c1e5ab2ed9f02f;p=mono.git diff --git a/mcs/gmcs/namespace.cs b/mcs/gmcs/namespace.cs old mode 100755 new mode 100644 index 11c5a7ec736..ec0a8347be7 --- a/mcs/gmcs/namespace.cs +++ b/mcs/gmcs/namespace.cs @@ -13,8 +13,11 @@ namespace Mono.CSharp { /// /// Keeps track of the namespaces defined in the C# code. + /// + /// This is an Expression to allow it to be referenced in the + /// compiler parse/intermediate tree during name resolution. /// - public class Namespace : IAlias { + public class Namespace : FullNamedExpression, IAlias { static ArrayList all_namespaces = new ArrayList (); static Hashtable namespaces_map = new Hashtable (); @@ -31,6 +34,11 @@ namespace Mono.CSharp { /// public Namespace (Namespace parent, string name) { + // Expression members. + this.eclass = ExprClass.Namespace; + this.Type = null; + this.loc = Location.Null; + this.parent = parent; string pname = parent != null ? parent.Name : ""; @@ -50,6 +58,16 @@ namespace Mono.CSharp { namespaces_map [fullname] = true; } + public override Expression DoResolve (EmitContext ec) + { + return this; + } + + public override void Emit (EmitContext ec) + { + throw new InternalErrorException ("Expression tree referenced namespace " + fullname + " during Emit ()"); + } + public static bool IsNamespace (string name) { return namespaces_map [name] != null; @@ -88,17 +106,19 @@ namespace Mono.CSharp { return Root.GetNamespace (name, create); } - public IAlias Lookup (DeclSpace ds, string name, Location loc) + public FullNamedExpression Lookup (DeclSpace ds, string name, Location loc) { - IAlias o = Lookup (name); + IAlias o = (IAlias) defined_names [name]; Type t; DeclSpace tdecl = o as DeclSpace; if (tdecl != null) { t = tdecl.DefineType (); + if (t == null) + return null; if ((ds == null) || ds.CheckAccessLevel (t)) - return new TypeExpression (t, loc); + return new TypeExpression (t, Location.Null); } Namespace ns = GetNamespace (name, false); @@ -109,7 +129,7 @@ namespace Mono.CSharp { if ((t == null) || ((ds != null) && !ds.CheckAccessLevel (t))) return null; - return new TypeExpression (t, loc); + return new TypeExpression (t, Location.Null); } public void AddNamespaceEntry (NamespaceEntry entry) @@ -122,11 +142,6 @@ namespace Mono.CSharp { defined_names.Add (name, o); } - public IAlias Lookup (string name) - { - return (IAlias) defined_names [name]; - } - static public ArrayList UserDefinedNamespaces { get { return all_namespaces; @@ -142,6 +157,12 @@ namespace Mono.CSharp { } } + public override string FullName { + get { + return fullname; + } + } + /// /// The parent of this namespace, used by the parser to "Pop" /// the current namespace declaration @@ -184,10 +205,9 @@ namespace Mono.CSharp { get { return false; } } - TypeExpr IAlias.Type { - get { - throw new InvalidOperationException (); - } + TypeExpr IAlias.ResolveAsType (EmitContext ec) + { + throw new InvalidOperationException (); } } @@ -227,14 +247,8 @@ namespace Mono.CSharp { if (resolved_ns != null) return resolved_ns; - Namespace curr_ns = NamespaceEntry.NS; - while ((curr_ns != null) && (resolved_ns == null)) { - resolved_ns = curr_ns.GetNamespace (Name, false); - - if (resolved_ns == null) - curr_ns = curr_ns.Parent; - } - + FullNamedExpression resolved = NamespaceEntry.LookupForUsing (Name, Location); + resolved_ns = resolved as Namespace; return resolved_ns; } } @@ -253,36 +267,30 @@ namespace Mono.CSharp { Location = loc; } - IAlias resolved; + FullNamedExpression resolved; - public IAlias Resolve () + public FullNamedExpression Resolve () { if (resolved != null) return resolved; - NamespaceEntry curr_ns = NamespaceEntry; - // // GENERICS: Cope with the expression and not with the string // this will fail with `using A = Stack' // string alias = Alias.GetTypeName (); - while ((curr_ns != null) && (resolved == null)) { - resolved = curr_ns.Lookup ( - null, alias, Alias.CountTypeArguments, - false, Location); - - if (resolved == null) - curr_ns = curr_ns.Parent; - } + resolved = NamespaceEntry.LookupForUsing (alias, Location); if (resolved == null) return null; - if (resolved.IsType) - resolved = new TypeAliasExpression ( - resolved.Type, Alias.TypeArguments, Location); + if (Alias.TypeArguments == null) + return resolved; + + EmitContext ec = RootContext.Tree.Types.EmitContext; + resolved = new TypeAliasExpression (resolved, Alias.TypeArguments, Location); + resolved = resolved.ResolveAsTypeStep (ec); return resolved; } @@ -359,14 +367,13 @@ namespace Mono.CSharp { if (using_clauses == null) using_clauses = new ArrayList (); - if (RootContext.WarningLevel >= 3) { - foreach (UsingEntry old_entry in using_clauses){ - if (old_entry.Name == ns){ + foreach (UsingEntry old_entry in using_clauses) { + if (old_entry.Name == ns) { + if (RootContext.WarningLevel >= 3) Report.Warning (105, loc, "The using directive for '{0}' appeared previously in this namespace", ns); return; } } - } UsingEntry ue = new UsingEntry (this, ns, loc); using_clauses.Add (ue); @@ -391,43 +398,79 @@ namespace Mono.CSharp { aliases [name] = new AliasEntry (this, name, alias, loc); } - protected AliasEntry GetAliasEntry (string alias) + public FullNamedExpression LookupAlias (string alias) { AliasEntry entry = null; - if (aliases != null) entry = (AliasEntry) aliases [alias]; - if (entry == null && Parent != null) - entry = Parent.GetAliasEntry (alias); - return entry; + return entry == null ? null : entry.Resolve (); } - public IAlias LookupAlias (string alias) + // + // According to section 16.3.1 (using-alias-directive), the namespace-or-type-name is + // resolved as if the immediately containing namespace body has no using-directives. + // + // Section 16.3.2 says that the same rule is applied when resolving the namespace-name + // in the using-namespace-directive. + // + public FullNamedExpression LookupForUsing (string dotted_name, Location loc) { - AliasEntry entry = GetAliasEntry (alias); + int pos = dotted_name.IndexOf ('.'); + string simple_name = dotted_name; + string rest = null; + if (pos >= 0) { + simple_name = dotted_name.Substring (0, pos); + rest = dotted_name.Substring (pos + 1); + } + + FullNamedExpression o = NS.Lookup (null, simple_name, loc); + if (o == null && ImplicitParent != null) + o = ImplicitParent.LookupNamespaceOrType (null, simple_name, loc); + + if (o == null || rest == null) + return o; - if (entry == null) + Namespace ns = o as Namespace; + if (ns != null) + return ns.Lookup (null, rest, loc); + + Type nested = TypeManager.LookupType (o.FullName + "." + rest); + if (nested == null) return null; - return entry.Resolve (); + return new TypeExpression (nested, Location.Null); } - public IAlias Lookup (DeclSpace ds, string name, int num_type_params, - bool silent, Location loc) + public FullNamedExpression LookupNamespaceOrType (DeclSpace ds, string name, Location loc) { - IAlias o; + FullNamedExpression resolved = null; + for (NamespaceEntry curr_ns = this; curr_ns != null; curr_ns = curr_ns.ImplicitParent) { + if ((resolved = curr_ns.Lookup (ds, name, loc)) != null) + break; + } + return resolved; + } + + private FullNamedExpression Lookup (DeclSpace ds, string name, Location loc) + { + FullNamedExpression o; Namespace ns; // // If name is of the form `N.I', first lookup `N', then search a member `I' in it. // + // FIXME: Remove this block. Only simple names should come here. + // The bug: The loop in LookupNamespaceOrType continues if + // the lookup for N succeeds but the nested lookup for I fails. + // This is one part of #52697. + // int pos = name.IndexOf ('.'); if (pos >= 0) { string first = name.Substring (0, pos); string last = name.Substring (pos + 1); - o = Lookup (ds, first, 0, silent, loc); + o = Lookup (ds, first, loc); if (o == null) return null; @@ -437,15 +480,15 @@ namespace Mono.CSharp { return o; } - Type nested = TypeManager.LookupType (o.Name + "." + last); + Type nested = TypeManager.LookupType (o.FullName + "." + last); if ((nested == null) || ((ds != null) && !ds.CheckAccessLevel (nested))) return null; - return new TypeExpression (nested, loc); + return new TypeExpression (nested, Location.Null); } // - // Check whether it's a namespace. + // Check whether it's in the namespace. // o = NS.Lookup (ds, name, loc); if (o != null) @@ -454,12 +497,9 @@ namespace Mono.CSharp { // // Check aliases. // - AliasEntry entry = GetAliasEntry (name); - if (entry != null) { - IAlias alias = entry.Resolve (); - if (alias != null) - return alias; - } + o = LookupAlias (name); + if (o != null) + return o; if (name.IndexOf ('.') > 0) return null; @@ -467,13 +507,12 @@ namespace Mono.CSharp { // // Check using entries. // - IAlias t = null, match = null; + FullNamedExpression t = null, match = null; foreach (Namespace using_ns in GetUsingTable ()) { match = using_ns.Lookup (ds, name, loc); - if ((match != null) && match.IsType){ + if ((match != null) && (match is TypeExpr)) { if (t != null) { - if (!silent) - DeclSpace.Error_AmbiguousTypeReference (loc, name, t.Name, match.Name); + DeclSpace.Error_AmbiguousTypeReference (loc, name, t.FullName, match.FullName); return null; } else { t = match; @@ -490,9 +529,11 @@ namespace Mono.CSharp { { if (namespace_using_table != null) return namespace_using_table; - - if (using_clauses == null) - return new Namespace [0]; + + if (using_clauses == null) { + namespace_using_table = new Namespace [0]; + return namespace_using_table; + } ArrayList list = new ArrayList (using_clauses.Count); @@ -539,53 +580,41 @@ namespace Mono.CSharp { } } - static void Msgtry (string s) + static void MsgtryRef (string s) { Console.WriteLine (" Try using -r:" + s); } + + static void MsgtryPkg (string s) + { + Console.WriteLine (" Try using -pkg:" + s); + } protected void error246 (Location loc, string name) { - if (TypeManager.LookupType (name) != null) - Report.Error (138, loc, "The using keyword only lets you specify a namespace, " + - "`" + name + "' is a class not a namespace."); - else { - Report.Error (246, loc, "The namespace `" + name + - "' can not be found (missing assembly reference?)"); - - switch (name){ - case "Gtk": case "GtkSharp": - Msgtry ("gtk-sharp"); - break; - - case "Gdk": case "GdkSharp": - Msgtry ("gdk-sharp"); - break; - - case "Glade": case "GladeSharp": - Msgtry ("glade-sharp"); - break; - - case "System.Drawing": - Msgtry ("System.Drawing"); - break; - - case "System.Web.Services": - Msgtry ("System.Web.Services"); - break; - - case "System.Web": - Msgtry ("System.Web"); - break; - - case "System.Data": - Msgtry ("System.Data"); - break; - - case "System.Windows.Forms": - Msgtry ("System.Windows.Forms"); - break; - } + Report.Error (246, loc, "The namespace `" + name + + "' can not be found (missing assembly reference?)"); + + switch (name) { + case "Gtk": case "GtkSharp": + MsgtryPkg ("gtk-sharp"); + break; + + case "Gdk": case "GdkSharp": + MsgtryPkg ("gdk-sharp"); + break; + + case "Glade": case "GladeSharp": + MsgtryPkg ("glade-sharp"); + break; + + case "System.Drawing": + case "System.Web.Services": + case "System.Web": + case "System.Data": + case "System.Windows.Forms": + MsgtryRef (name); + break; } } @@ -595,32 +624,28 @@ namespace Mono.CSharp { /// public void VerifyUsing () { - TypeContainer dummy = new RootTypes (); - EmitContext ec = new EmitContext ( - dummy, Location.Null, null, null, 0, false); - if (using_clauses != null){ foreach (UsingEntry ue in using_clauses){ if (ue.Resolve () != null) continue; - error246 (ue.Location, ue.Name); + if (LookupForUsing (ue.Name, ue.Location) == null) + error246 (ue.Location, ue.Name); + else + Report.Error (138, ue.Location, "The using keyword only lets you specify a namespace, " + + "`" + ue.Name + "' is a class not a namespace."); + } } if (aliases != null){ foreach (DictionaryEntry de in aliases){ - AliasEntry entry = (AliasEntry) de.Value; - - IAlias alias = entry.Resolve (); - if (alias != null) { - if (alias.IsType) - alias.Type.ResolveType (ec); + AliasEntry alias = (AliasEntry) de.Value; + if (alias.Resolve () != null) continue; - } - error246 (entry.Location, entry.Alias.ToString ()); + error246 (alias.Location, alias.Alias.GetTypeName ()); } } }