2010-01-12 Zoltan Varga <vargaz@gmail.com>
[mcs.git] / mcs / roottypes.cs
blobcb823e1a7fe992b1559a1e8822578a842729e093
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 readonly bool is_unsafe;
30 readonly CompilerContext context;
32 bool has_default_charset;
34 public CharSet DefaultCharSet = CharSet.Ansi;
35 public TypeAttributes DefaultCharSetType = TypeAttributes.AnsiClass;
37 static readonly string[] attribute_targets = new string[] { "module" };
39 public ModuleContainer (CompilerContext context, bool isUnsafe)
40 : base (null, null, MemberName.Null, null, Kind.Root)
42 this.is_unsafe = isUnsafe;
43 this.context = context;
45 types = new ArrayList ();
46 anonymous_types = new Hashtable ();
49 public override AttributeTargets AttributeTargets {
50 get {
51 return AttributeTargets.Module;
55 public void AddAnonymousType (AnonymousTypeClass type)
57 ArrayList existing = (ArrayList)anonymous_types [type.Parameters.Count];
58 if (existing == null) {
59 existing = new ArrayList ();
60 anonymous_types.Add (type.Parameters.Count, existing);
62 existing.Add (type);
65 public void AddAttributes (ArrayList attrs)
67 foreach (Attribute a in attrs)
68 a.AttachTo (this, CodeGen.Assembly);
70 if (attributes == null) {
71 attributes = new Attributes (attrs);
72 return;
75 attributes.AddAttributes (attrs);
78 public override TypeContainer AddPartial (TypeContainer nextPart)
80 return AddPartial (nextPart, nextPart.Name);
83 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
85 if (a.Type == pa.CLSCompliant) {
86 if (CodeGen.Assembly.ClsCompliantAttribute == null) {
87 Report.Warning (3012, 1, a.Location, "You must specify the CLSCompliant attribute on the assembly, not the module, to enable CLS compliance checking");
88 } else if (CodeGen.Assembly.IsClsCompliant != a.GetBoolean ()) {
89 Report.SymbolRelatedToPreviousError (CodeGen.Assembly.ClsCompliantAttribute.Location, CodeGen.Assembly.ClsCompliantAttribute.GetSignatureForError ());
90 Report.Warning (3017, 1, a.Location, "You cannot specify the CLSCompliant attribute on a module that differs from the CLSCompliant attribute on the assembly");
91 return;
95 Builder.SetCustomAttribute (cb);
98 public override CompilerContext Compiler {
99 get { return context; }
102 public override void Emit ()
104 if (OptAttributes != null)
105 OptAttributes.Emit ();
107 if (is_unsafe) {
108 Type t = TypeManager.CoreLookupType (context, "System.Security", "UnverifiableCodeAttribute", Kind.Class, true);
109 if (t != null) {
110 ConstructorInfo unverifiable_code_ctor = TypeManager.GetPredefinedConstructor (t, Location.Null, Type.EmptyTypes);
111 if (unverifiable_code_ctor != null)
112 Builder.SetCustomAttribute (new CustomAttributeBuilder (unverifiable_code_ctor, new object [0]));
117 public AnonymousTypeClass GetAnonymousType (ArrayList parameters)
119 ArrayList candidates = (ArrayList) anonymous_types [parameters.Count];
120 if (candidates == null)
121 return null;
123 int i;
124 foreach (AnonymousTypeClass at in candidates) {
125 for (i = 0; i < parameters.Count; ++i) {
126 if (!parameters [i].Equals (at.Parameters [i]))
127 break;
130 if (i == parameters.Count)
131 return at;
134 return null;
137 public override bool GetClsCompliantAttributeValue ()
139 return CodeGen.Assembly.IsClsCompliant;
142 public bool HasDefaultCharSet {
143 get {
144 return has_default_charset;
148 public override string GetSignatureForError ()
150 return "<module>";
153 public override bool IsClsComplianceRequired ()
155 return true;
158 public override ModuleContainer Module {
159 get {
160 return this;
164 protected override bool AddMemberType (DeclSpace ds)
166 if (!AddToContainer (ds, ds.Name))
167 return false;
168 ds.NamespaceEntry.NS.AddDeclSpace (ds.Basename, ds);
169 return true;
172 protected override void RemoveMemberType (DeclSpace ds)
174 ds.NamespaceEntry.NS.RemoveDeclSpace (ds.Basename);
175 base.RemoveMemberType (ds);
178 /// <summary>
179 /// It is called very early therefore can resolve only predefined attributes
180 /// </summary>
181 public void Resolve ()
183 if (OptAttributes == null)
184 return;
186 if (!OptAttributes.CheckTargets ())
187 return;
189 Attribute a = ResolveAttribute (PredefinedAttributes.Get.DefaultCharset);
190 if (a != null) {
191 has_default_charset = true;
192 DefaultCharSet = a.GetCharSetValue ();
193 switch (DefaultCharSet) {
194 case CharSet.Ansi:
195 case CharSet.None:
196 break;
197 case CharSet.Auto:
198 DefaultCharSetType = TypeAttributes.AutoClass;
199 break;
200 case CharSet.Unicode:
201 DefaultCharSetType = TypeAttributes.UnicodeClass;
202 break;
203 default:
204 Report.Error (1724, a.Location, "Value specified for the argument to 'System.Runtime.InteropServices.DefaultCharSetAttribute' is not valid");
205 break;
210 Attribute ResolveAttribute (PredefinedAttribute a_type)
212 Attribute a = OptAttributes.Search (a_type);
213 if (a != null) {
214 a.Resolve ();
216 return a;
219 public override string[] ValidAttributeTargets {
220 get {
221 return attribute_targets;
226 class RootDeclSpace : DeclSpace {
227 public RootDeclSpace (NamespaceEntry ns)
228 : base (ns, null, MemberName.Null, null)
230 PartialContainer = RootContext.ToplevelTypes;
233 public override AttributeTargets AttributeTargets {
234 get { throw new InternalErrorException ("should not be called"); }
237 public override CompilerContext Compiler {
238 get {
239 return PartialContainer.Compiler;
243 public override string DocCommentHeader {
244 get { throw new InternalErrorException ("should not be called"); }
247 public override bool Define ()
249 throw new InternalErrorException ("should not be called");
252 public override TypeBuilder DefineType ()
254 throw new InternalErrorException ("should not be called");
257 public override MemberCache MemberCache {
258 get { return PartialContainer.MemberCache; }
261 public override ModuleContainer Module {
262 get {
263 return PartialContainer.Module;
267 public override bool GetClsCompliantAttributeValue ()
269 return PartialContainer.GetClsCompliantAttributeValue ();
272 public override bool IsClsComplianceRequired ()
274 return PartialContainer.IsClsComplianceRequired ();
277 public override FullNamedExpression LookupNamespaceAlias (string name)
279 return NamespaceEntry.LookupNamespaceAlias (name);