2001-06-13 Miguel de Icaza <miguel@ximian.com>
[mono.git] / mcs / mcs / tree.cs
1 //
2 // tree.cs: keeps a tree representation of the generated code
3 //
4 // Author: Miguel de Icaza (miguel@gnu.org)
5 //
6 // Licensed under the terms of the GNU GPL
7 //
8 // (C) 2001 Ximian, Inc (http://www.ximian.com)
9 //
10 //
11
12 using System;
13 using System.Collections;
14 using System.Reflection;
15 using System.Reflection.Emit;
16
17 namespace CIR
18 {
19
20         // <summary>
21         //   A storage for temporary IL trees
22         // </summary>
23         
24         public class Tree {
25                 TypeContainer root_types;
26
27                 // <summary>
28                 //   Holds the Array of Assemblies that have been loaded
29                 //   (either because it is the default or the user used the
30                 //   -r command line option)
31                 // </summary>
32                 ArrayList assemblies;
33
34                 // <summary>
35                 //   This is used to map defined FQN to Types
36                 // </summary>
37                 Hashtable types;
38
39                 // <summary>
40                 //   This maps source defined types that are defined
41                 //   in the source code to their object holders (Class, Struct, 
42                 //   Interface) and that have not yet been made into real
43                 //   types. 
44                 // </summary>
45                 Hashtable source_types;
46
47                 AppDomain current_domain;
48                 AssemblyBuilder assembly_builder;
49                 ModuleBuilder   module_builder;
50                 
51                 public Tree ()
52                 {
53                         root_types = new TypeContainer (null, "");
54                         assemblies = new ArrayList ();
55                         types = new Hashtable ();
56                         source_types = new Hashtable ();
57                 }
58
59                 public int BuilderInit (string name, string output)
60                 {
61                         AssemblyName an;
62                         
63                         an = new AssemblyName ();
64                         an.Name = "AssemblyName";
65                         current_domain = AppDomain.CurrentDomain;
66                         assembly_builder = current_domain.DefineDynamicAssembly (
67                                 an, AssemblyBuilderAccess.RunAndSave);
68
69                         module_builder = assembly_builder.DefineDynamicModule (name, output);
70
71                         return 0;
72                 }
73
74                 public AssemblyBuilder AssemblyBuilder {
75                         get {
76                                 return assembly_builder;
77                         }
78                 }
79
80                 public ModuleBuilder ModuleBuilder {
81                         get {
82                                 return module_builder;
83                         }
84                 }
85
86                 public void RecordType (string name, DeclSpace decl)
87                 {
88                         source_types.Add (name, decl);
89                 }
90                 
91                 public TypeContainer Types {
92                         get {
93                                 return root_types;
94                         }
95                 }
96
97                 public int ResolveTypeContainerTypes (TypeContainer type)
98                 {
99                         return 0;
100                 }
101                 
102                 public int ResolveNames (TypeContainer types)
103                 {
104                         int errors = 0;
105                         
106                         if (types == null)
107                                 return 0;
108
109                         foreach (DictionaryEntry de in types.Types){
110                                 TypeContainer type = (TypeContainer) de.Value;
111
112                                 errors += ResolveTypeContainerTypes (type);
113                         }
114
115                         return errors;
116                 }
117
118                 public Type ResolveType (string name)
119                 {
120                         Type t = (Type) types [name];
121                         
122                         if (t != null)
123                                 return t;
124
125                         DeclSpace decl;
126                         decl = (DeclSpace) source_types [name];
127
128                         // FIXME: handle using here.
129                         if (decl == null){
130                                 CSC.CSharpParser.error (234, "The type or namespace name '" + name
131                                                         + "' does not exist in the current space");
132                                 return null;
133                         }
134
135                         return decl.Define (this);
136                 }
137                 
138                 int iscan_errors = 0;
139                 void interface_scan (TypeContainer container, object data)
140                 {
141                         foreach (Interface iface in container.Interfaces){
142                                 Type t = ResolveType (iface.Name);
143
144                                 if (t != null){
145                                         CSC.CSharpParser.error (101, "There is already a definition for " + iface.Name);
146                                         iscan_errors++;
147                                 }
148                                 iface.Define (this);
149                         }
150                 }
151
152                 public int ResolveInterfaces (TypeContainer type)
153                 {
154                         TypeContainer.VisitContainer iscanner;
155
156                         iscanner = new TypeContainer.VisitContainer (interface_scan);
157                         type.VisitTypes (iscanner, this);
158                         return iscan_errors;
159                 }
160                 
161                 public int ResolveTypeContainerParents (TypeContainer type)
162                 {
163                         return type.ResolveParents (this);
164                 }
165
166                 public int Resolve ()
167                 {
168                         int errors = 0;
169
170                         errors += ResolveInterfaces (root_types);
171                         errors += ResolveTypeContainerParents (root_types);
172                         return 0;
173                 }
174
175                 public void AddAssembly (Assembly a)
176                 {
177                         assemblies.Add (a);
178                         foreach (Type t in a.GetExportedTypes ()){
179                                 types.Add (t.FullName, t);
180                         }
181                 }
182         }
183 }