2 // namespace.cs: Tracks namespaces
5 // Miguel de Icaza (miguel@ximian.com)
7 // (C) 2001 Ximian, Inc.
10 using System.Collections;
13 namespace Mono.CSharp {
16 /// Keeps track of the namespaces defined in the C# code.
18 public class Namespace {
19 static ArrayList all_namespaces = new ArrayList ();
25 ArrayList using_clauses;
27 public bool DeclarationFound = false;
30 // This class holds the location where a using definition is
31 // done, and whether it has been used by the program or not.
33 // We use this to flag using clauses for namespaces that do not
36 public class UsingEntry {
38 public Location Location;
40 public UsingEntry (string name, Location loc)
48 /// Constructor Takes the current namespace and the
49 /// name. This is bootstrapped with parent == null
52 public Namespace (Namespace parent, SourceFile file, string name)
58 all_namespaces.Add (this);
61 static public ArrayList UserDefinedNamespaces {
63 return all_namespaces;
68 /// The qualified name of the current namespace
72 string pname = parent != null ? parent.Name : "";
77 return String.Concat (parent.Name, ".", name);
82 /// The parent of this namespace, used by the parser to "Pop"
83 /// the current namespace declaration
85 public Namespace Parent {
91 public int SymbolFileID {
98 /// Records a new namespace for resolving name references
100 public void Using (string ns, Location loc)
102 if (DeclarationFound){
103 Report.Error (1529, loc, "A using clause must precede all other namespace elements");
110 if (using_clauses == null)
111 using_clauses = new ArrayList ();
113 foreach (UsingEntry old_entry in using_clauses){
114 if (old_entry.Name == ns){
115 Report.Warning (105, loc, "The using directive for '" + ns +
116 "' appeared previously in this namespace");
121 UsingEntry ue = new UsingEntry (ns, loc);
122 using_clauses.Add (ue);
125 public ArrayList UsingTable {
127 return using_clauses;
131 public void UsingAlias (string alias, string namespace_or_type, Location loc)
134 aliases = new Hashtable ();
136 if (aliases.Contains (alias)){
137 Report.Error (1537, loc, "The using alias `" + alias +
138 "' appeared previously in this namespace");
142 aliases [alias] = namespace_or_type;
145 public string LookupAlias (string alias)
149 // System.Console.WriteLine ("Lookup " + alias + " in " + name);
152 value = (string) (aliases [alias]);
153 if (value == null && Parent != null)
154 value = Parent.LookupAlias (alias);
159 void DefineNamespace (SymbolWriter symwriter)
164 parent.DefineNamespace (symwriter);
167 if (using_clauses != null) {
168 using_list = new string [using_clauses.Count];
169 for (int i = 0; i < using_clauses.Count; i++)
170 using_list [i] = ((UsingEntry) using_clauses [i]).Name;
172 using_list = new string [0];
175 int parent_id = parent != null ? parent.symfile_id : 0;
176 symfile_id = symwriter.DefineNamespace (name, file, using_list, parent_id);
179 public static void DefineNamespaces (SymbolWriter symwriter)
181 foreach (Namespace ns in all_namespaces)
182 ns.DefineNamespace (symwriter);
186 /// Used to validate that all the using clauses are correct
187 /// after we are finished parsing all the files.
189 public static void VerifyUsing ()
191 foreach (Namespace ns in all_namespaces){
192 ArrayList uses = ns.UsingTable;
195 foreach (UsingEntry ue in uses){
196 if (TypeManager.IsNamespace (ue.Name))
199 Report.Error (246, ue.Location, "The namespace `" + ue.Name +
200 "' can not be found (missing assembly reference?)");
204 if (ns.aliases != null){
205 foreach (DictionaryEntry de in ns.aliases){
206 string value = (string) de.Value;
208 if (TypeManager.IsNamespace (value))
210 if (TypeManager.LookupTypeDirect (value) != null)
213 Report.Error (246, String.Format (
214 "The type or namespace `{0}' could not be found (missing assembly reference?)",