/// <summary>
/// Keeps track of the namespaces defined in the C# code.
/// </summary>
- public class Namespace {
+ public class Namespace : IAlias {
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)
+ public IAlias Lookup (DeclSpace ds, string name, Location loc)
{
+ IAlias o = Lookup (name);
+
+ Type t;
+ DeclSpace tdecl = o as DeclSpace;
+ if (tdecl != null) {
+ t = tdecl.DefineType ();
+
+ if ((ds == null) || ds.CheckAccessLevel (t))
+ return new TypeExpression (t, loc);
+ }
+
Namespace ns = GetNamespace (name, false);
if (ns != null)
return ns;
- Type t = TypeManager.LookupType (DeclSpace.MakeFQN (fullname, name));
+ t = TypeManager.LookupType (DeclSpace.MakeFQN (fullname, name));
if ((t == null) || ((ds != null) && !ds.CheckAccessLevel (t)))
return null;
- return t;
+ return new TypeExpression (t, loc);
}
public void AddNamespaceEntry (NamespaceEntry entry)
entries.Add (entry);
}
+ public void DefineName (string name, IAlias o)
+ {
+ defined_names.Add (name, o);
+ }
+
+ public IAlias Lookup (string name)
+ {
+ return (IAlias) defined_names [name];
+ }
+
static public ArrayList UserDefinedNamespaces {
get {
return all_namespaces;
else
return String.Format ("Namespace ({0})", Name);
}
+
+ bool IAlias.IsType {
+ get { return false; }
+ }
+
+ TypeExpr IAlias.Type {
+ get {
+ throw new InvalidOperationException ();
+ }
+ }
}
public class NamespaceEntry
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 MemberName 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, MemberName alias, Location loc)
{
Name = name;
Alias = alias;
Location = loc;
}
- object resolved;
+ IAlias resolved;
- public object Resolve ()
+ public IAlias 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<int>'
+ //
+
+ string alias = Alias.GetTypeName ();
+
+ // According to section 16.3.1, the namespace-or-type-name is resolved
+ // as if the immediately containing namespace body has no using-directives.
+ resolved = NamespaceEntry.Lookup (
+ null, alias, Alias.CountTypeArguments, true, false, Location);
+
+ NamespaceEntry curr_ns = NamespaceEntry.Parent;
+
while ((curr_ns != null) && (resolved == null)) {
- resolved = curr_ns.Lookup (null, Alias, Location);
+ resolved = curr_ns.Lookup (
+ null, alias, Alias.CountTypeArguments,
+ false, false, Location);
if (resolved == null)
curr_ns = curr_ns.Parent;
}
+ if (resolved == null)
+ return null;
+
+ if (resolved.IsType)
+ resolved = new TypeAliasExpression (
+ resolved.Type, Alias.TypeArguments, Location);
+
return resolved;
}
}
- 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, IAlias 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 = 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;
}
}
using_clauses.Add (ue);
}
- public void UsingAlias (string alias, string namespace_or_type, 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 ();
-
- if (aliases.Contains (alias)){
- Report.Error (1537, loc, "The using alias `" + alias +
+
+ if (aliases.Contains (name)){
+ Report.Error (1537, loc, "The using alias `" + name +
"' appeared previously in this namespace");
return;
}
- aliases [alias] = new AliasEntry (this, alias, namespace_or_type, loc);
+ aliases [name] = new AliasEntry (this, name, alias, loc);
}
protected AliasEntry GetAliasEntry (string alias)
return entry;
}
- public string LookupAlias (string alias)
+ public IAlias LookupAlias (string alias)
{
AliasEntry entry = GetAliasEntry (alias);
if (entry == null)
return null;
- object resolved = entry.Resolve ();
- if (resolved == null)
- return null;
- else if (resolved is Namespace)
- return ((Namespace) resolved).Name;
- else
- return ((Type) resolved).FullName;
+ return entry.Resolve ();
}
- public object Lookup (DeclSpace ds, string name, Location loc)
+ public IAlias Lookup (DeclSpace ds, string name, int num_type_params,
+ bool ignore_using, bool silent, Location loc)
{
- object o;
+ IAlias o;
Namespace ns;
//
string first = name.Substring (0, pos);
string last = name.Substring (pos + 1);
- o = Lookup (ds, first, loc);
+ o = Lookup (ds, first, 0, ignore_using, silent, loc);
if (o == null)
return null;
ns = o as Namespace;
- if (ns != null)
- return ns.Lookup (ds, last);
+ if (ns != null) {
+ o = ns.Lookup (ds, last, loc);
+ return o;
+ }
- Type nested = TypeManager.LookupType (DeclSpace.MakeFQN (((Type) o).Name, last));
+ Type nested = TypeManager.LookupType (o.Name + "." + last);
if ((nested == null) || ((ds != null) && !ds.CheckAccessLevel (nested)))
return null;
- return nested;
+ return new TypeExpression (nested, loc);
}
//
// Check whether it's a namespace.
//
- o = NS.Lookup (ds, name);
+ o = NS.Lookup (ds, name, loc);
if (o != null)
return o;
+ if (ignore_using)
+ return null;
+
//
// Check aliases.
//
AliasEntry entry = GetAliasEntry (name);
if (entry != null) {
- o = entry.Resolve ();
- if (o != null)
- return o;
+ IAlias alias = entry.Resolve ();
+ if (alias != null)
+ return alias;
}
+ if (name.IndexOf ('.') > 0)
+ return null;
+
//
// Check using entries.
//
- Type t = null, match = null;
+ IAlias t = null, match = null;
foreach (Namespace using_ns in GetUsingTable ()) {
- match = using_ns.Lookup (ds, name) as Type;
- if (match != null){
+ match = using_ns.Lookup (ds, name, loc);
+ if ((match != null) && match.IsType){
if (t != null) {
- DeclSpace.Error_AmbiguousTypeReference (loc, name, t, match);
+ if (!silent)
+ DeclSpace.Error_AmbiguousTypeReference (loc, name, t.Name, match.Name);
return null;
} else {
t = match;
}
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 {
/// </summary>
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)
if (aliases != null){
foreach (DictionaryEntry de in aliases){
- AliasEntry alias = (AliasEntry) de.Value;
+ AliasEntry entry = (AliasEntry) de.Value;
+
+ IAlias alias = entry.Resolve ();
+ if (alias != null) {
+ if (alias.IsType)
+ alias.Type.ResolveType (ec);
- if (alias.Resolve () != null)
continue;
+ }
- error246 (alias.Location, alias.Alias);
+ error246 (entry.Location, entry.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);
}
}
}