2002-01-31 Duncan Mak <duncan@ximian.com>
[mono.git] / mcs / mcs / namespace.cs
1 //
2 // namespace.cs: Tracks namespaces
3 //
4 // Author:
5 //   Miguel de Icaza (miguel@ximian.com)
6 //
7 // (C) 2001 Ximian, Inc.
8 //
9 using System;
10 using System.Collections;
11
12 namespace Mono.CSharp {
13
14         /// <summary>
15         ///   Keeps track of the namespaces defined in the C# code.
16         /// </summary>
17         public class Namespace {
18                 Namespace parent;
19                 string name;
20                 ArrayList using_clauses;
21                 Hashtable aliases;
22                 bool decl_found = false;
23                 
24                 /// <summary>
25                 ///   Constructor Takes the current namespace and the
26                 ///   name.  This is bootstrapped with parent == null
27                 ///   and name = ""
28                 /// </summary>
29                 public Namespace (Namespace parent, string name)
30                 {
31                         this.name = name;
32                         this.parent = parent;
33                 }
34
35                 /// <summary>
36                 ///   The qualified name of the current namespace
37                 /// </summary>
38                 public string Name {
39                         get {
40                                 string pname = parent != null ? parent.Name : "";
41                                 
42                                 if (pname == "")
43                                         return name;
44                                 else
45                                         return parent.Name + "." + name;
46                         }
47                 }
48
49                 /// <summary>
50                 ///   The parent of this namespace, used by the parser to "Pop"
51                 ///   the current namespace declaration
52                 /// </summary>
53                 public Namespace Parent {
54                         get {
55                                 return parent;
56                         }
57                 }
58
59                 /// <summary>
60                 ///   When a declaration is found in a namespace,
61                 ///   we call this function, to emit an error if the
62                 ///   program attempts to use a using clause afterwards
63                 /// </summary>
64                 public void DeclarationFound ()
65                 {
66                         decl_found = true;
67                 }
68
69                 /// <summary>
70                 ///   Records a new namespace for resolving name references
71                 /// </summary>
72                 public void Using (string ns)
73                 {
74                         if (decl_found){
75                                 CSharpParser.error (1529, "A using clause must precede all other namespace elements");
76                                 return;
77                         }
78
79                         if (using_clauses == null)
80                                 using_clauses = new ArrayList ();
81
82                         using_clauses.Add (ns);
83                 }
84
85                 public ArrayList UsingTable {
86                         get {
87                                 return using_clauses;
88                         }
89                 }
90
91                 public void UsingAlias (string alias, string namespace_or_type, Location loc)
92                 {
93                         if (aliases == null)
94                                 aliases = new Hashtable ();
95                         
96                         if (aliases.Contains (alias)){
97                                 Report.Error (1537, loc, "The using alias `" + alias +
98                                               "' appeared previously in this namespace");
99                                 return;
100                         }
101                                         
102                         aliases [alias] = namespace_or_type;
103                 }
104
105                 public string LookupAlias (string alias)
106                 {
107                         string value = null;
108
109                         // System.Console.WriteLine ("Lookup " + alias + " in " + name);
110
111                         if (aliases != null)
112                                 value = (string) (aliases [alias]);
113                         if (value == null && Parent != null)
114                                 value = Parent.LookupAlias (alias);
115
116                         return value;
117                 }
118
119                 /// <summary>
120                 ///   Used to validate that all the using clauses are correct
121                 ///   after we are finished parsing all the files
122                 /// </summary>
123                 public void VerifyUsing ()
124                 {
125                         foreach (DictionaryEntry de in using_clauses){
126                                 if (de.Value == null){
127                                         string name = (string) de.Key;
128                                         
129                                         CSharpParser.error (234, "The type or namespace `" +
130                                                             name + "' does not exist in the " +
131                                                             "class or namespace `" + name + "'");
132                                 }
133                         }
134                 }
135
136         }
137 }
138