X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;ds=sidebyside;f=mcs%2Fgmcs%2Fnamespace.cs;h=ec0a8347be7f965ea04df864df213b262a8c2377;hb=cffda3181a45b81bbf989a128da6f7a5047a6a99;hp=6e3fbda610fe0c5dd336d6353706d118043e58f1;hpb=75d01eb61789ad0505aef1c17d78e869ce91c69d;p=mono.git diff --git a/mcs/gmcs/namespace.cs b/mcs/gmcs/namespace.cs old mode 100755 new mode 100644 index 6e3fbda610f..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,25 +247,19 @@ 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; } } public class AliasEntry { public readonly string Name; - public readonly TypeName Alias; + public readonly MemberName Alias; public readonly NamespaceEntry NamespaceEntry; public readonly Location Location; - public AliasEntry (NamespaceEntry entry, string name, TypeName alias, Location loc) + public AliasEntry (NamespaceEntry entry, string name, MemberName alias, Location loc) { Name = name; Alias = alias; @@ -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 (true); - while ((curr_ns != null) && (resolved == null)) { - resolved = curr_ns.Lookup ( - null, alias, Alias.CountTypeArguments, - Location); - - if (resolved == null) - curr_ns = curr_ns.Parent; - } + string alias = Alias.GetTypeName (); + 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,20 +367,25 @@ namespace Mono.CSharp { if (using_clauses == null) using_clauses = new ArrayList (); - foreach (UsingEntry old_entry in using_clauses){ - if (old_entry.Name == ns){ - Report.Warning (105, loc, "The using directive for '" + ns + - "' appeared previously in this namespace"); - return; + 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); } - public void UsingAlias (string name, TypeName alias, Location loc) + public void UsingAlias (string name, MemberName alias, Location loc) { + if (DeclarationFound){ + Report.Error (1529, loc, "A using clause must precede all other namespace elements"); + return; + } + if (aliases == null) aliases = new Hashtable (); @@ -385,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, - 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, loc); + o = Lookup (ds, first, loc); if (o == null) return null; @@ -431,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) @@ -448,22 +497,22 @@ 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; // // 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) { - DeclSpace.Error_AmbiguousTypeReference (loc, name, t.Name, match.Name); + DeclSpace.Error_AmbiguousTypeReference (loc, name, t.FullName, match.FullName); return null; } else { t = match; @@ -480,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); @@ -516,7 +567,11 @@ namespace Mono.CSharp { } int parent_id = parent != null ? parent.symfile_id : 0; - symfile_id = symwriter.DefineNamespace (ns.Name, file, using_list, parent_id); + if (file.SourceFileEntry == null) + return; + + symfile_id = symwriter.DefineNamespace ( + ns.Name, file.SourceFileEntry, using_list, parent_id); } public int SymbolFileID { @@ -525,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; } } @@ -581,32 +624,28 @@ namespace Mono.CSharp { /// public void VerifyUsing () { - TypeContainer dummy = new TypeContainer (); - 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 ()); } } }