2009-11-15 Jb Evain <jbevain@novell.com>
[mcs.git] / mcs / roottypes.cs
blob0c9b6b23e7793a0f8ee41ffdf223fede16d977bf
1 //
2 // roottypes.cs: keeps a tree representation of the generated code
3 //
4 // Authors: Miguel de Icaza (miguel@gnu.org)
5 // Marek Safar (marek.safar@gmail.com)
6 //
7 // Dual licensed under the terms of the MIT X11 or GNU GPL
8 //
9 // Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
10 // Copyright 2003-2008 Novell, Inc.
13 using System;
14 using System.Collections;
15 using System.Reflection;
16 using System.Reflection.Emit;
17 using System.Runtime.InteropServices;
19 namespace Mono.CSharp
22 // Module container, it can be used as a top-level type
24 public class ModuleContainer : TypeContainer
26 public CharSet DefaultCharSet = CharSet.Ansi;
27 public TypeAttributes DefaultCharSetType = TypeAttributes.AnsiClass;
29 protected Assembly assembly;
31 public ModuleContainer (Assembly assembly)
32 : base (null, null, MemberName.Null, null, Kind.Root)
34 this.assembly = assembly;
37 public Assembly Assembly {
38 get { return assembly; }
41 // FIXME: Remove this evil one day
42 public ModuleCompiled Compiled {
43 get { return (ModuleCompiled) this; }
46 public override ModuleContainer Module {
47 get {
48 return this;
54 // Compiled top-level types
56 public class ModuleCompiled : ModuleContainer
58 // TODO: It'd be so nice to have generics
59 Hashtable anonymous_types;
60 readonly bool is_unsafe;
61 readonly CompilerContext context;
63 ModuleBuilder builder;
65 bool has_default_charset;
67 static readonly string[] attribute_targets = new string[] { "module" };
69 public ModuleCompiled (CompilerContext context, bool isUnsafe)
70 : base (null)
72 this.is_unsafe = isUnsafe;
73 this.context = context;
75 types = new ArrayList ();
76 anonymous_types = new Hashtable ();
79 public override AttributeTargets AttributeTargets {
80 get {
81 return AttributeTargets.Module;
85 public void AddAnonymousType (AnonymousTypeClass type)
87 ArrayList existing = (ArrayList)anonymous_types [type.Parameters.Count];
88 if (existing == null) {
89 existing = new ArrayList ();
90 anonymous_types.Add (type.Parameters.Count, existing);
92 existing.Add (type);
95 public void AddAttributes (ArrayList attrs)
97 foreach (Attribute a in attrs)
98 a.AttachTo (this, CodeGen.Assembly);
100 if (attributes == null) {
101 attributes = new Attributes (attrs);
102 return;
105 attributes.AddAttributes (attrs);
108 public override TypeContainer AddPartial (TypeContainer nextPart)
110 return AddPartial (nextPart, nextPart.Name);
113 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
115 if (a.Type == pa.CLSCompliant) {
116 if (CodeGen.Assembly.ClsCompliantAttribute == null) {
117 Report.Warning (3012, 1, a.Location, "You must specify the CLSCompliant attribute on the assembly, not the module, to enable CLS compliance checking");
118 } else if (CodeGen.Assembly.IsClsCompliant != a.GetBoolean ()) {
119 Report.SymbolRelatedToPreviousError (CodeGen.Assembly.ClsCompliantAttribute.Location, CodeGen.Assembly.ClsCompliantAttribute.GetSignatureForError ());
120 Report.Warning (3017, 1, a.Location, "You cannot specify the CLSCompliant attribute on a module that differs from the CLSCompliant attribute on the assembly");
121 return;
125 builder.SetCustomAttribute (cb);
128 public ModuleBuilder Builder {
129 get {
130 return builder;
133 set {
134 builder = value;
135 assembly = builder.Assembly;
139 public override CompilerContext Compiler {
140 get { return context; }
143 public override void Emit ()
145 if (OptAttributes != null)
146 OptAttributes.Emit ();
148 if (is_unsafe) {
149 Type t = TypeManager.CoreLookupType (context, "System.Security", "UnverifiableCodeAttribute", Kind.Class, true);
150 if (t != null) {
151 ConstructorInfo unverifiable_code_ctor = TypeManager.GetPredefinedConstructor (t, Location.Null, Type.EmptyTypes);
152 if (unverifiable_code_ctor != null)
153 builder.SetCustomAttribute (new CustomAttributeBuilder (unverifiable_code_ctor, new object [0]));
158 public AnonymousTypeClass GetAnonymousType (ArrayList parameters)
160 ArrayList candidates = (ArrayList) anonymous_types [parameters.Count];
161 if (candidates == null)
162 return null;
164 int i;
165 foreach (AnonymousTypeClass at in candidates) {
166 for (i = 0; i < parameters.Count; ++i) {
167 if (!parameters [i].Equals (at.Parameters [i]))
168 break;
171 if (i == parameters.Count)
172 return at;
175 return null;
178 public override bool GetClsCompliantAttributeValue ()
180 return CodeGen.Assembly.IsClsCompliant;
183 public bool HasDefaultCharSet {
184 get {
185 return has_default_charset;
189 public override string GetSignatureForError ()
191 return "<module>";
194 public override bool IsClsComplianceRequired ()
196 return true;
199 protected override bool AddMemberType (DeclSpace ds)
201 if (!AddToContainer (ds, ds.Name))
202 return false;
203 ds.NamespaceEntry.NS.AddDeclSpace (ds.Basename, ds);
204 return true;
207 protected override void RemoveMemberType (DeclSpace ds)
209 ds.NamespaceEntry.NS.RemoveDeclSpace (ds.Basename);
210 base.RemoveMemberType (ds);
213 /// <summary>
214 /// It is called very early therefore can resolve only predefined attributes
215 /// </summary>
216 public void Resolve ()
218 if (OptAttributes == null)
219 return;
221 if (!OptAttributes.CheckTargets ())
222 return;
224 Attribute a = ResolveAttribute (PredefinedAttributes.Get.DefaultCharset);
225 if (a != null) {
226 has_default_charset = true;
227 DefaultCharSet = a.GetCharSetValue ();
228 switch (DefaultCharSet) {
229 case CharSet.Ansi:
230 case CharSet.None:
231 break;
232 case CharSet.Auto:
233 DefaultCharSetType = TypeAttributes.AutoClass;
234 break;
235 case CharSet.Unicode:
236 DefaultCharSetType = TypeAttributes.UnicodeClass;
237 break;
238 default:
239 Report.Error (1724, a.Location, "Value specified for the argument to 'System.Runtime.InteropServices.DefaultCharSetAttribute' is not valid");
240 break;
245 Attribute ResolveAttribute (PredefinedAttribute a_type)
247 Attribute a = OptAttributes.Search (a_type);
248 if (a != null) {
249 a.Resolve ();
251 return a;
254 public override string[] ValidAttributeTargets {
255 get {
256 return attribute_targets;
261 class RootDeclSpace : DeclSpace {
262 public RootDeclSpace (NamespaceEntry ns)
263 : base (ns, null, MemberName.Null, null)
265 PartialContainer = RootContext.ToplevelTypes;
268 public override AttributeTargets AttributeTargets {
269 get { throw new InternalErrorException ("should not be called"); }
272 public override CompilerContext Compiler {
273 get {
274 return PartialContainer.Compiler;
278 public override string DocCommentHeader {
279 get { throw new InternalErrorException ("should not be called"); }
282 public override bool Define ()
284 throw new InternalErrorException ("should not be called");
287 public override TypeBuilder DefineType ()
289 throw new InternalErrorException ("should not be called");
292 public override MemberCache MemberCache {
293 get { return PartialContainer.MemberCache; }
296 public override ModuleContainer Module {
297 get {
298 return PartialContainer.Module;
302 public override bool GetClsCompliantAttributeValue ()
304 return PartialContainer.GetClsCompliantAttributeValue ();
307 public override bool IsClsComplianceRequired ()
309 return PartialContainer.IsClsComplianceRequired ();
312 public override FullNamedExpression LookupNamespaceAlias (string name)
314 return NamespaceEntry.LookupNamespaceAlias (name);