//
using System;
using System.Collections;
-using Mono.Languages;
namespace Mono.CSharp {
/// </summary>
public class Namespace {
static ArrayList all_namespaces = new ArrayList ();
+ static Hashtable namespaces_map = new Hashtable ();
Namespace parent;
- string name, fullname;
+ string fullname;
ArrayList entries;
Hashtable namespaces;
+ Hashtable defined_names;
/// <summary>
/// Constructor Takes the current namespace and the
/// </summary>
public Namespace (Namespace parent, string name)
{
- this.name = name;
this.parent = parent;
string pname = parent != null ? parent.Name : "";
entries = new ArrayList ();
namespaces = new Hashtable ();
+ defined_names = new Hashtable ();
all_namespaces.Add (this);
+ if (namespaces_map.Contains (fullname))
+ return;
+ namespaces_map [fullname] = true;
}
+ public static bool IsNamespace (string name)
+ {
+ return namespaces_map [name] != null;
+ }
+
public static Namespace Root = new Namespace (null, "");
public Namespace GetNamespace (string name, bool create)
return Root.GetNamespace (name, create);
}
+ public object Lookup (DeclSpace ds, string name)
+ {
+ object o = Lookup (name);
+
+ Type t;
+ DeclSpace tdecl = o as DeclSpace;
+ if (tdecl != null) {
+ t = tdecl.DefineType ();
+
+ if ((ds == null) || ds.CheckAccessLevel (t))
+ return t;
+ }
+
+ Namespace ns = GetNamespace (name, false);
+ if (ns != null)
+ return ns;
+
+ t = TypeManager.LookupType (DeclSpace.MakeFQN (fullname, name));
+ if ((t == null) || ((ds != null) && !ds.CheckAccessLevel (t)))
+ return null;
+
+ return t;
+ }
+
public void AddNamespaceEntry (NamespaceEntry entry)
{
entries.Add (entry);
}
+ public void DefineName (string name, object o)
+ {
+ defined_names.Add (name, o);
+ }
+
+ public object Lookup (string name)
+ {
+ return defined_names [name];
+ }
+
static public ArrayList UserDefinedNamespaces {
get {
return all_namespaces;
Namespace curr_ns = NamespaceEntry.NS;
while ((curr_ns != null) && (resolved_ns == null)) {
- string full_name = DeclSpace.MakeFQN (curr_ns.Name, Name);
resolved_ns = curr_ns.GetNamespace (Name, false);
if (resolved_ns == null)
public class AliasEntry {
public readonly string Name;
- public readonly string Alias;
+ public readonly Expression Alias;
public readonly NamespaceEntry NamespaceEntry;
public readonly Location Location;
- public AliasEntry (NamespaceEntry entry, string name, string alias, Location loc)
+ public AliasEntry (NamespaceEntry entry, string name, Expression alias, Location loc)
{
Name = name;
Alias = alias;
if (resolved != null)
return resolved;
- int pos = Alias.IndexOf ('.');
- if (pos >= 0) {
- string first = Alias.Substring (0, pos);
- }
-
NamespaceEntry curr_ns = NamespaceEntry;
+
+ //
+ // GENERICS: Cope with the expression and not with the string
+ // this will fail with `using A = Stack<int>'
+ //
+
+ string alias = Alias.ToString ();
while ((curr_ns != null) && (resolved == null)) {
- string full_name = DeclSpace.MakeFQN (curr_ns.Name, Alias);
- resolved = curr_ns.LookupName (Alias);
+ resolved = curr_ns.Lookup (null, alias, Location);
if (resolved == null)
curr_ns = curr_ns.Parent;
}
}
- public NamespaceEntry (NamespaceEntry parent, SourceFile file, string name)
- : this (parent, file, name, false)
+ public NamespaceEntry (NamespaceEntry parent, SourceFile file, string name, Location loc)
+ : this (parent, file, name, false, loc)
{ }
- protected NamespaceEntry (NamespaceEntry parent, SourceFile file, string name, bool is_implicit)
+ protected NamespaceEntry (NamespaceEntry parent, SourceFile file, string name, bool is_implicit, Location loc)
{
this.parent = parent;
this.file = file;
ns.AddNamespaceEntry (this);
if ((parent != null) && (parent.NS != ns.Parent))
- implicit_parent = new NamespaceEntry (parent, file, ns.Parent.Name, true);
+ implicit_parent = new NamespaceEntry (parent, file, ns.Parent.Name, true, loc);
else
implicit_parent = parent;
+
+ this.FullName = ns.Name;
}
static int next_id = 0;
+ public readonly string FullName;
public readonly int ID;
public readonly bool IsImplicit;
- public string Name {
- get {
- return ns.Name;
- }
- }
-
public Namespace NS {
get {
return ns;
}
}
+ public void DefineName (string name, object o)
+ {
+ ns.DefineName (name, o);
+ }
+
/// <summary>
/// Records a new namespace for resolving name references
/// </summary>
return;
}
- if (ns == Name)
+ if (ns == FullName)
return;
if (using_clauses == null)
using_clauses.Add (ue);
}
- public void UsingAlias (string alias, string namespace_or_type, Location loc)
+ public void UsingAlias (string alias, Expression namespace_or_type, Location loc)
{
if (aliases == null)
aliases = new Hashtable ();
return ((Type) resolved).FullName;
}
- public object LookupName (string name)
+ public object Lookup (DeclSpace ds, string name, Location loc)
{
- Namespace ns = Namespace.LookupNamespace (name, false);
- if (ns != null)
- return ns;
+ object o;
+ Namespace ns;
+ //
+ // If name is of the form `N.I', first lookup `N', then search a member `I' in it.
+ //
int pos = name.IndexOf ('.');
- AliasEntry alias = null;
if (pos >= 0) {
string first = name.Substring (0, pos);
string last = name.Substring (pos + 1);
- alias = GetAliasEntry (first);
- if (alias != null)
- return LookupName (DeclSpace.MakeFQN (alias.Alias, last));
+ o = Lookup (ds, first, loc);
+ if (o == null)
+ return null;
+
+ ns = o as Namespace;
+ if (ns != null)
+ return ns.Lookup (ds, last);
+
+ Type nested = TypeManager.LookupType ((((Type) o).Name + "." + last));
+ if ((nested == null) || ((ds != null) && !ds.CheckAccessLevel (nested)))
+ return null;
+
+ return nested;
}
- Type t = TypeManager.LookupType (name);
- if (t != null)
- return t;
+ //
+ // Check whether it's a namespace.
+ //
+ o = NS.Lookup (ds, name);
+ if (o != null)
+ return o;
+
+ //
+ // Check aliases.
+ //
+ AliasEntry entry = GetAliasEntry (name);
+ if (entry != null) {
+ o = entry.Resolve ();
+ if (o != null)
+ return o;
+ }
- alias = GetAliasEntry (name);
- if (alias != null)
- return LookupName (alias.Alias);
+ //
+ // Check using entries.
+ //
+ Type t = null, match = null;
+ foreach (Namespace using_ns in GetUsingTable ()) {
+ match = using_ns.Lookup (ds, name) as Type;
+ if (match != null){
+ if (t != null) {
+ DeclSpace.Error_AmbiguousTypeReference (loc, name, t, match);
+ return null;
+ } else {
+ t = match;
+ }
+ }
+ }
- return null;
+ return t;
}
-
+
+ // Our cached computation.
+ Namespace [] namespace_using_table;
public Namespace[] GetUsingTable ()
{
- ArrayList list = new ArrayList ();
-
+ if (namespace_using_table != null)
+ return namespace_using_table;
+
if (using_clauses == null)
return new Namespace [0];
+ ArrayList list = new ArrayList (using_clauses.Count);
+
foreach (UsingEntry ue in using_clauses) {
Namespace using_ns = ue.Resolve ();
if (using_ns == null)
list.Add (using_ns);
}
- Namespace[] retval = new Namespace [list.Count];
- list.CopyTo (retval, 0);
- return retval;
+ namespace_using_table = new Namespace [list.Count];
+ list.CopyTo (namespace_using_table, 0);
+ return namespace_using_table;
}
public void DefineNamespace (SymbolWriter symwriter)
if (alias.Resolve () != null)
continue;
- error246 (alias.Location, alias.Alias);
+ error246 (alias.Location, alias.Alias.ToString ());
}
}
}
if (NS == Namespace.Root)
return "NamespaceEntry (<root>)";
else
- return String.Format ("NamespaceEntry ({0},{1},{2})", Name, IsImplicit, ID);
+ return String.Format ("NamespaceEntry ({0},{1},{2})", FullName, IsImplicit, ID);
}
}
}