2010-04-07 Jb Evain <jbevain@novell.com>
[mcs.git] / mcs / roottypes.cs
blob116c3da3827a2e04a643f9acac49f2ea12fd282e
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.Generic;
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, 0)
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 Dictionary<int, List<AnonymousTypeClass>> anonymous_types;
59 readonly bool is_unsafe;
60 readonly CompilerContext context;
62 ModuleBuilder builder;
64 bool has_default_charset;
66 static readonly string[] attribute_targets = new string[] { "module" };
68 public ModuleCompiled (CompilerContext context, bool isUnsafe)
69 : base (null)
71 this.is_unsafe = isUnsafe;
72 this.context = context;
74 types = new List<TypeContainer> ();
75 anonymous_types = new Dictionary<int, List<AnonymousTypeClass>> ();
78 public override AttributeTargets AttributeTargets {
79 get {
80 return AttributeTargets.Module;
84 public void AddAnonymousType (AnonymousTypeClass type)
86 List<AnonymousTypeClass> existing;
87 if (!anonymous_types.TryGetValue (type.Parameters.Count, out existing))
88 if (existing == null) {
89 existing = new List<AnonymousTypeClass> ();
90 anonymous_types.Add (type.Parameters.Count, existing);
93 existing.Add (type);
96 public void AddAttributes (List<Attribute> attrs)
98 foreach (Attribute a in attrs)
99 a.AttachTo (this, CodeGen.Assembly);
101 if (attributes == null) {
102 attributes = new Attributes (attrs);
103 return;
106 attributes.AddAttributes (attrs);
109 public override TypeContainer AddPartial (TypeContainer nextPart)
111 return AddPartial (nextPart, nextPart.Name);
114 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
116 if (a.Type == pa.CLSCompliant) {
117 if (CodeGen.Assembly.ClsCompliantAttribute == null) {
118 Report.Warning (3012, 1, a.Location, "You must specify the CLSCompliant attribute on the assembly, not the module, to enable CLS compliance checking");
119 } else if (CodeGen.Assembly.IsClsCompliant != a.GetBoolean ()) {
120 Report.SymbolRelatedToPreviousError (CodeGen.Assembly.ClsCompliantAttribute.Location, CodeGen.Assembly.ClsCompliantAttribute.GetSignatureForError ());
121 Report.Warning (3017, 1, a.Location, "You cannot specify the CLSCompliant attribute on a module that differs from the CLSCompliant attribute on the assembly");
122 return;
126 builder.SetCustomAttribute (cb);
129 public ModuleBuilder Builder {
130 get {
131 return builder;
134 set {
135 builder = value;
136 assembly = builder.Assembly;
140 public override CompilerContext Compiler {
141 get { return context; }
144 public override void Emit ()
146 if (OptAttributes != null)
147 OptAttributes.Emit ();
149 if (is_unsafe) {
150 Type t = TypeManager.CoreLookupType (context, "System.Security", "UnverifiableCodeAttribute", MemberKind.Class, true);
151 if (t != null) {
152 ConstructorInfo unverifiable_code_ctor = TypeManager.GetPredefinedConstructor (t, Location.Null, Type.EmptyTypes);
153 if (unverifiable_code_ctor != null)
154 builder.SetCustomAttribute (new CustomAttributeBuilder (unverifiable_code_ctor, new object [0]));
159 public AnonymousTypeClass GetAnonymousType (IList<AnonymousTypeParameter> parameters)
161 List<AnonymousTypeClass> candidates;
162 if (!anonymous_types.TryGetValue (parameters.Count, out candidates))
163 return null;
165 int i;
166 foreach (AnonymousTypeClass at in candidates) {
167 for (i = 0; i < parameters.Count; ++i) {
168 if (!parameters [i].Equals (at.Parameters [i]))
169 break;
172 if (i == parameters.Count)
173 return at;
176 return null;
179 public override bool GetClsCompliantAttributeValue ()
181 return CodeGen.Assembly.IsClsCompliant;
184 public bool HasDefaultCharSet {
185 get {
186 return has_default_charset;
190 public override string GetSignatureForError ()
192 return "<module>";
195 public override bool IsClsComplianceRequired ()
197 return true;
200 protected override bool AddMemberType (DeclSpace ds)
202 if (!AddToContainer (ds, ds.Name))
203 return false;
204 ds.NamespaceEntry.NS.AddDeclSpace (ds.Basename, ds);
205 return true;
208 protected override void RemoveMemberType (DeclSpace ds)
210 ds.NamespaceEntry.NS.RemoveDeclSpace (ds.Basename);
211 base.RemoveMemberType (ds);
214 /// <summary>
215 /// It is called very early therefore can resolve only predefined attributes
216 /// </summary>
217 public void Resolve ()
219 if (OptAttributes == null)
220 return;
222 if (!OptAttributes.CheckTargets ())
223 return;
225 Attribute a = ResolveAttribute (PredefinedAttributes.Get.DefaultCharset);
226 if (a != null) {
227 has_default_charset = true;
228 DefaultCharSet = a.GetCharSetValue ();
229 switch (DefaultCharSet) {
230 case CharSet.Ansi:
231 case CharSet.None:
232 break;
233 case CharSet.Auto:
234 DefaultCharSetType = TypeAttributes.AutoClass;
235 break;
236 case CharSet.Unicode:
237 DefaultCharSetType = TypeAttributes.UnicodeClass;
238 break;
239 default:
240 Report.Error (1724, a.Location, "Value specified for the argument to 'System.Runtime.InteropServices.DefaultCharSetAttribute' is not valid");
241 break;
246 Attribute ResolveAttribute (PredefinedAttribute a_type)
248 Attribute a = OptAttributes.Search (a_type);
249 if (a != null) {
250 a.Resolve ();
252 return a;
255 public override string[] ValidAttributeTargets {
256 get {
257 return attribute_targets;
262 class RootDeclSpace : DeclSpace {
263 public RootDeclSpace (NamespaceEntry ns)
264 : base (ns, null, MemberName.Null, null)
266 PartialContainer = RootContext.ToplevelTypes;
269 public override AttributeTargets AttributeTargets {
270 get { throw new InternalErrorException ("should not be called"); }
273 public override CompilerContext Compiler {
274 get {
275 return PartialContainer.Compiler;
279 public override string DocCommentHeader {
280 get { throw new InternalErrorException ("should not be called"); }
283 public override bool Define ()
285 throw new InternalErrorException ("should not be called");
288 public override TypeBuilder DefineType ()
290 throw new InternalErrorException ("should not be called");
293 public override MemberCache MemberCache {
294 get { return PartialContainer.MemberCache; }
297 public override ModuleContainer Module {
298 get {
299 return PartialContainer.Module;
303 public override bool GetClsCompliantAttributeValue ()
305 return PartialContainer.GetClsCompliantAttributeValue ();
308 public override bool IsClsComplianceRequired ()
310 return PartialContainer.IsClsComplianceRequired ();
313 public override FullNamedExpression LookupNamespaceAlias (string name)
315 return NamespaceEntry.LookupNamespaceAlias (name);