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 {
39 public Location Location;
41 public UsingEntry (string name, Location loc)
50 /// Constructor Takes the current namespace and the
51 /// name. This is bootstrapped with parent == null
54 public Namespace (Namespace parent, SourceFile file, string name)
60 all_namespaces.Add (this);
64 /// The qualified name of the current namespace
68 string pname = parent != null ? parent.Name : "";
73 return String.Concat (parent.Name, ".", name);
78 /// The parent of this namespace, used by the parser to "Pop"
79 /// the current namespace declaration
81 public Namespace Parent {
87 public int SymbolFileID {
94 /// Records a new namespace for resolving name references
96 public void Using (string ns, Location loc)
98 if (DeclarationFound){
99 Report.Error (1529, loc, "A using clause must precede all other namespace elements");
106 if (using_clauses == null)
107 using_clauses = new ArrayList ();
109 foreach (UsingEntry old_entry in using_clauses){
110 if (old_entry.Name == ns){
111 Report.Warning (105, loc, "The using directive for '" + ns +
112 "' appeared previously in this namespace");
117 UsingEntry ue = new UsingEntry (ns, loc);
118 using_clauses.Add (ue);
121 public ArrayList UsingTable {
123 return using_clauses;
127 public void UsingAlias (string alias, string namespace_or_type, Location loc)
130 aliases = new Hashtable ();
132 if (aliases.Contains (alias)){
133 Report.Error (1537, loc, "The using alias `" + alias +
134 "' appeared previously in this namespace");
138 aliases [alias] = namespace_or_type;
141 public string LookupAlias (string alias)
145 // System.Console.WriteLine ("Lookup " + alias + " in " + name);
148 value = (string) (aliases [alias]);
149 if (value == null && Parent != null)
150 value = Parent.LookupAlias (alias);
155 void DefineNamespace (SymbolWriter symwriter)
160 parent.DefineNamespace (symwriter);
163 if (using_clauses != null) {
164 using_list = new string [using_clauses.Count];
165 for (int i = 0; i < using_clauses.Count; i++)
166 using_list [i] = ((UsingEntry) using_clauses [i]).Name;
168 using_list = new string [0];
171 int parent_id = parent != null ? parent.symfile_id : 0;
172 symfile_id = symwriter.DefineNamespace (name, file, using_list, parent_id);
175 public static void DefineNamespaces (SymbolWriter symwriter)
177 foreach (Namespace ns in all_namespaces)
178 ns.DefineNamespace (symwriter);
182 /// Used to validate that all the using clauses are correct
183 /// after we are finished parsing all the files.
185 public static bool VerifyUsing ()
187 ArrayList unused = new ArrayList ();
190 foreach (Namespace ns in all_namespaces){
191 ArrayList uses = ns.UsingTable;
195 foreach (UsingEntry ue in uses){
203 // If we have unused using aliases, load all namespaces and check
204 // whether it is unused, or it was missing
206 if (unused.Count > 0){
207 Hashtable namespaces = TypeManager.GetNamespaces ();
209 foreach (UsingEntry ue in unused){
210 if (namespaces.Contains (ue.Name)){
211 Report.Warning (6024, ue.Location, "Unused namespace in `using' declaration");
216 Report.Error (246, ue.Location, "The namespace `" + ue.Name +
217 "' can not be found (missing assembly reference?)");