2009-07-28 Jb Evain <jbevain@novell.com>
[mcs.git] / mcs / roottypes.cs
blobd3c235fe93aacf2d9c8564353d7ab986a85f7359
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 // Compiled top-level types
24 public sealed class ModuleContainer : TypeContainer
26 // TODO: It'd be so nice to have generics
27 Hashtable anonymous_types;
28 public ModuleBuilder Builder;
29 bool is_unsafe;
31 bool has_default_charset;
33 public CharSet DefaultCharSet = CharSet.Ansi;
34 public TypeAttributes DefaultCharSetType = TypeAttributes.AnsiClass;
36 static readonly string[] attribute_targets = new string[] { "module" };
38 public ModuleContainer (bool isUnsafe)
39 : base (null, null, MemberName.Null, null, Kind.Root)
41 this.is_unsafe = isUnsafe;
42 types = new ArrayList ();
43 anonymous_types = new Hashtable ();
46 public override AttributeTargets AttributeTargets {
47 get {
48 return AttributeTargets.Module;
52 public void AddAnonymousType (AnonymousTypeClass type)
54 ArrayList existing = (ArrayList)anonymous_types [type.Parameters.Count];
55 if (existing == null) {
56 existing = new ArrayList ();
57 anonymous_types.Add (type.Parameters.Count, existing);
59 existing.Add (type);
62 public void AddAttributes (ArrayList attrs)
64 foreach (Attribute a in attrs)
65 a.AttachTo (this);
67 if (attributes == null) {
68 attributes = new Attributes (attrs);
69 return;
72 attributes.AddAttributes (attrs);
75 public override TypeContainer AddPartial (TypeContainer nextPart)
77 return AddPartial (nextPart, nextPart.Name);
80 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
82 if (a.Type == pa.CLSCompliant) {
83 if (CodeGen.Assembly.ClsCompliantAttribute == null) {
84 Report.Warning (3012, 1, a.Location, "You must specify the CLSCompliant attribute on the assembly, not the module, to enable CLS compliance checking");
85 } else if (CodeGen.Assembly.IsClsCompliant != a.GetBoolean ()) {
86 Report.SymbolRelatedToPreviousError (CodeGen.Assembly.ClsCompliantAttribute.Location, CodeGen.Assembly.ClsCompliantAttribute.GetSignatureForError ());
87 Report.Warning (3017, 1, a.Location, "You cannot specify the CLSCompliant attribute on a module that differs from the CLSCompliant attribute on the assembly");
88 return;
92 Builder.SetCustomAttribute (cb);
95 public override void Emit ()
97 if (OptAttributes != null)
98 OptAttributes.Emit ();
100 if (is_unsafe) {
101 Type t = TypeManager.CoreLookupType ("System.Security", "UnverifiableCodeAttribute", Kind.Class, true);
102 if (t != null) {
103 ConstructorInfo unverifiable_code_ctor = TypeManager.GetPredefinedConstructor (t, Location.Null, Type.EmptyTypes);
104 if (unverifiable_code_ctor != null)
105 Builder.SetCustomAttribute (new CustomAttributeBuilder (unverifiable_code_ctor, new object [0]));
110 public AnonymousTypeClass GetAnonymousType (ArrayList parameters)
112 ArrayList candidates = (ArrayList) anonymous_types [parameters.Count];
113 if (candidates == null)
114 return null;
116 int i;
117 foreach (AnonymousTypeClass at in candidates) {
118 for (i = 0; i < parameters.Count; ++i) {
119 if (!parameters [i].Equals (at.Parameters [i]))
120 break;
123 if (i == parameters.Count)
124 return at;
127 return null;
130 public override bool GetClsCompliantAttributeValue ()
132 return CodeGen.Assembly.IsClsCompliant;
135 public bool HasDefaultCharSet {
136 get {
137 return has_default_charset;
141 public override string GetSignatureForError ()
143 return "<module>";
146 public override bool IsClsComplianceRequired ()
148 return true;
151 public override ModuleContainer Module {
152 get {
153 return this;
157 public override IResolveContext ResolveContext {
158 get { return this; }
161 protected override bool AddMemberType (DeclSpace ds)
163 if (!AddToContainer (ds, ds.Name))
164 return false;
165 ds.NamespaceEntry.NS.AddDeclSpace (ds.Basename, ds);
166 return true;
169 protected override void RemoveMemberType (DeclSpace ds)
171 ds.NamespaceEntry.NS.RemoveDeclSpace (ds.Basename);
172 base.RemoveMemberType (ds);
175 /// <summary>
176 /// It is called very early therefore can resolve only predefined attributes
177 /// </summary>
178 public void Resolve ()
180 if (OptAttributes == null)
181 return;
183 if (!OptAttributes.CheckTargets ())
184 return;
186 Attribute a = ResolveAttribute (PredefinedAttributes.Get.DefaultCharset);
187 if (a != null) {
188 has_default_charset = true;
189 DefaultCharSet = a.GetCharSetValue ();
190 switch (DefaultCharSet) {
191 case CharSet.Ansi:
192 case CharSet.None:
193 break;
194 case CharSet.Auto:
195 DefaultCharSetType = TypeAttributes.AutoClass;
196 break;
197 case CharSet.Unicode:
198 DefaultCharSetType = TypeAttributes.UnicodeClass;
199 break;
200 default:
201 Report.Error (1724, a.Location, "Value specified for the argument to 'System.Runtime.InteropServices.DefaultCharSetAttribute' is not valid");
202 break;
207 Attribute ResolveAttribute (PredefinedAttribute a_type)
209 Attribute a = OptAttributes.Search (a_type);
210 if (a != null) {
211 a.Resolve ();
213 return a;
216 public override string[] ValidAttributeTargets {
217 get {
218 return attribute_targets;
223 class RootDeclSpace : DeclSpace {
224 public RootDeclSpace (NamespaceEntry ns)
225 : base (ns, null, MemberName.Null, null)
227 PartialContainer = RootContext.ToplevelTypes;
230 public override AttributeTargets AttributeTargets {
231 get { throw new InternalErrorException ("should not be called"); }
234 public override string DocCommentHeader {
235 get { throw new InternalErrorException ("should not be called"); }
238 public override bool Define ()
240 throw new InternalErrorException ("should not be called");
243 public override TypeBuilder DefineType ()
245 throw new InternalErrorException ("should not be called");
248 public override MemberCache MemberCache {
249 get { return PartialContainer.MemberCache; }
252 public override ModuleContainer Module {
253 get {
254 return PartialContainer.Module;
258 public override bool GetClsCompliantAttributeValue ()
260 return PartialContainer.GetClsCompliantAttributeValue ();
263 public override bool IsClsComplianceRequired ()
265 return PartialContainer.IsClsComplianceRequired ();