Welcome to mirror list, hosted at ThFree Co, Russian Federation.

namespace.cs « mbas « mcs - github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: d310d9a4c80e70f032a8e539e3da4d44080da0c8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//
// namespace.cs: Tracks namespaces
//
// Author:
//   Miguel de Icaza (miguel@ximian.com)
//
// (C) 2001 Ximian, Inc.
//
using System;
using System.Collections;
using Mono.Languages;

namespace Mono.CSharp {

	/// <summary>
	///   Keeps track of the namespaces defined in the C# code.
	/// </summary>
	public class Namespace {
		Namespace parent;
		string name;
		ArrayList using_clauses;
		Hashtable aliases;
		bool decl_found = false;
		
		/// <summary>
		///   Constructor Takes the current namespace and the
		///   name.  This is bootstrapped with parent == null
		///   and name = ""
		/// </summary>
		public Namespace (Namespace parent, string name)
		{
			this.name = name;
			this.parent = parent;
		}

		/// <summary>
		///   The qualified name of the current namespace
		/// </summary>
		public string Name {
			get {
				string pname = parent != null ? parent.Name : "";
				
				if (pname == "")
					return name;
				else
					return parent.Name + "." + name;
			}
		}

		/// <summary>
		///   The parent of this namespace, used by the parser to "Pop"
		///   the current namespace declaration
		/// </summary>
		public Namespace Parent {
			get {
				return parent;
			}
		}

		/// <summary>
		///   When a declaration is found in a namespace,
		///   we call this function, to emit an error if the
		///   program attempts to use a using clause afterwards
		/// </summary>
		public void DeclarationFound ()
		{
			decl_found = true;
		}

		/// <summary>
		///   Records a new namespace for resolving name references
		/// </summary>
		public void Using (string ns)
		{
			if (decl_found){
				GenericParser.error (1529, "A using clause must precede all other namespace elements");
				return;
			}

			if (using_clauses == null)
				using_clauses = new ArrayList ();

			using_clauses.Add (ns);
		}

		public ArrayList UsingTable {
			get {
				return using_clauses;
			}
		}

		public void UsingAlias (string alias, string namespace_or_type, Location loc)
		{
			if (aliases == null)
				aliases = new Hashtable ();
			
			if (aliases.Contains (alias)){
				Report.Error (1537, loc, "The using alias `" + alias +
					      "' appeared previously in this namespace");
				return;
			}
					
			aliases [alias] = namespace_or_type;
		}

		public string LookupAlias (string alias)
		{
			string value = null;

			// System.Console.WriteLine ("Lookup " + alias + " in " + name);

			if (aliases != null)
				value = (string) (aliases [alias]);
			if (value == null && Parent != null)
				value = Parent.LookupAlias (alias);

			return value;
		}

		/// <summary>
		///   Used to validate that all the using clauses are correct
		///   after we are finished parsing all the files
		/// </summary>
		public void VerifyUsing ()
		{
			foreach (DictionaryEntry de in using_clauses){
				if (de.Value == null){
					string name = (string) de.Key;
					
					GenericParser.error (234, "The type or namespace `" +
							    name + "' does not exist in the " +
							    "class or namespace `" + name + "'");
				}
			}
		}

	}
}