Added VisualStudio files
[mono.git] / mcs / mcs / rootcontext.cs
1 //
2 // rootcontext.cs: keeps track of our tree representation, and assemblies loaded.
3 //
4 // Author: Miguel de Icaza (miguel@ximian.com)
5 //
6 // Licensed under the terms of the GNU GPL
7 //
8 // (C) 2001 Ximian, Inc (http://www.ximian.com)
9
10 using System;
11 using System.Collections;
12 using System.Reflection;
13 using System.Reflection.Emit;
14
15 namespace CIR {
16
17         public class RootContext {
18
19                 //
20                 // Contains the parsed tree
21                 //
22                 Tree tree;
23
24                 //
25                 // Contains loaded assemblies and our generated code as we go.
26                 //
27                 TypeManager type_manager;
28
29                 //
30                 // The System.Reflection.Emit CodeGenerator
31                 //
32                 CilCodeGen cg;
33
34                 ModuleBuilder mb;
35
36                 Report report;
37                 
38                 public RootContext ()
39                 {
40                         tree = new Tree ();
41                         type_manager = new TypeManager ();
42                         report = new Report ();
43                 }
44
45                 public TypeManager TypeManager {
46                         get {
47                                 return type_manager;
48                         }
49                 }
50
51                 public Tree Tree {
52                         get {
53                                 return tree;
54                         }
55                 }
56
57                 public CilCodeGen CodeGen {
58                         get {
59                                 return cg;
60                         }
61
62                         set {
63                                 //
64                                 // Temporary hack, we should probably
65                                 // intialize `cg' rather than depending on
66                                 // external initialization of it.
67                                 //
68                                 cg = value;
69                                 mb = cg.ModuleBuilder;
70                         }
71                 }
72
73                 //
74                 // Returns the list of interfaces that this interface implements
75                 // Null on error
76                 //
77                 Type [] GetInterfaces (Interface iface, out bool error)
78                 {
79                         ArrayList bases = iface.Bases;
80                         Hashtable source_ifaces;
81                         int count = bases.Count;
82                         Type [] tbases;
83                         int i;
84
85                         error = false;
86                         if (count == 0)
87                                 return null;
88                         
89                         tbases = new Type [bases.Count];
90                         i = 0;
91                         source_ifaces = tree.Interfaces;
92
93                         foreach (string name in iface.Bases){
94                                 Type t = type_manager.LookupType (name);
95                                 Interface parent;
96                                 
97                                 if (t != null){
98                                         tbases [i++] = t;
99                                         continue;
100                                 }
101                                 parent = (Interface) source_ifaces [name];
102                                 if (parent == null){
103                                         error = true;
104                                         report.Error (246, "Can not find type `"+name+"'");
105                                         return null;
106                                 }
107                                 t = CreateInterface (parent);
108                                 if (t == null){
109                                         report.Error (529,
110                                                       "Inherited interface `"+name+"' in `"+
111                                                       iface.Name+"' is recursive");
112                                         error = true;
113                                         return null;
114                                 }
115                                 tbases [i++] = t;
116                         }
117
118                         return tbases;
119                 }
120                 
121                 //
122                 // Creates the Interface @iface using the ModuleBuilder
123                 //
124                 // TODO:
125                 //   Resolve recursively dependencies.
126                 //
127                 TypeBuilder CreateInterface (Interface iface)
128                 {
129                         TypeBuilder tb;
130                         bool error;
131                         
132                         if (iface.InTransit)
133                                 return null;
134                         iface.InTransit = true;
135
136                         string name = iface.Name;
137                         Type [] ifaces = GetInterfaces (iface, out error);
138
139                         if (error)
140                                 return null;
141                         
142                         tb = mb.DefineType (name,
143                                             TypeAttributes.Interface |
144                                             TypeAttributes.Public |
145                                             TypeAttributes.Abstract,
146                                             null, ifaces);
147                         iface.Definition = tb;
148
149                         //
150                         // if Recursive_Def (child) == false
151                         //      error (child.Name recursive def with iface.Name)
152                         //
153                         type_manager.AddUserType (name, tb);
154
155                         iface.InTransit = false;
156                         return tb;
157                 }
158                 
159                 public void ResolveInterfaceBases ()
160                 {
161                         Hashtable ifaces = tree.Interfaces;
162
163                         if (ifaces == null)
164                                 return;
165
166                         foreach (Interface iface in ifaces){
167                                 string name = iface.Name;
168
169                                 CreateInterface (iface);
170                         }
171                 }
172
173                 public void ResolveClassBases ()
174                 {
175                 }
176
177                 // <summary>
178                 //   Closes all open types
179                 // </summary>
180                 //
181                 // <remarks>
182                 //   We usually use TypeBuilder types.  When we are done
183                 //   creating the type (which will happen after we have addded
184                 //   methods, fields, etc) we need to "Define" them before we
185                 //   can save the Assembly
186                 // </remarks>
187                 public void CloseTypes ()
188                 {
189                         foreach (TypeBuilder t in type_manager.UserTypes){
190                                 t.CreateType ();
191                         }
192                 }
193         }
194 }
195