2 // roottypes.cs: keeps a tree representation of the generated code
4 // Authors: Miguel de Icaza (miguel@gnu.org)
5 // Marek Safar (marek.safar@gmail.com)
7 // Dual licensed under the terms of the MIT X11 or GNU GPL
9 // Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
10 // Copyright 2003-2008 Novell, Inc.
14 using System
.Collections
;
15 using System
.Reflection
;
16 using System
.Reflection
.Emit
;
17 using System
.Runtime
.InteropServices
;
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
{
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
)
72 this.is_unsafe
= isUnsafe
;
73 this.context
= context
;
75 types
= new ArrayList ();
76 anonymous_types
= new Hashtable ();
79 public override AttributeTargets AttributeTargets
{
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
);
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
);
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");
125 builder
.SetCustomAttribute (cb
);
128 public ModuleBuilder Builder
{
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 ();
149 Type t
= TypeManager
.CoreLookupType (context
, "System.Security", "UnverifiableCodeAttribute", Kind
.Class
, true);
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)
165 foreach (AnonymousTypeClass at
in candidates
) {
166 for (i
= 0; i
< parameters
.Count
; ++i
) {
167 if (!parameters
[i
].Equals (at
.Parameters
[i
]))
171 if (i
== parameters
.Count
)
178 public override bool GetClsCompliantAttributeValue ()
180 return CodeGen
.Assembly
.IsClsCompliant
;
183 public bool HasDefaultCharSet
{
185 return has_default_charset
;
189 public override string GetSignatureForError ()
194 public override bool IsClsComplianceRequired ()
199 protected override bool AddMemberType (DeclSpace ds
)
201 if (!AddToContainer (ds
, ds
.Name
))
203 ds
.NamespaceEntry
.NS
.AddDeclSpace (ds
.Basename
, ds
);
207 protected override void RemoveMemberType (DeclSpace ds
)
209 ds
.NamespaceEntry
.NS
.RemoveDeclSpace (ds
.Basename
);
210 base.RemoveMemberType (ds
);
214 /// It is called very early therefore can resolve only predefined attributes
216 public void Resolve ()
218 if (OptAttributes
== null)
221 if (!OptAttributes
.CheckTargets ())
224 Attribute a
= ResolveAttribute (PredefinedAttributes
.Get
.DefaultCharset
);
226 has_default_charset
= true;
227 DefaultCharSet
= a
.GetCharSetValue ();
228 switch (DefaultCharSet
) {
233 DefaultCharSetType
= TypeAttributes
.AutoClass
;
235 case CharSet
.Unicode
:
236 DefaultCharSetType
= TypeAttributes
.UnicodeClass
;
239 Report
.Error (1724, a
.Location
, "Value specified for the argument to 'System.Runtime.InteropServices.DefaultCharSetAttribute' is not valid");
245 Attribute
ResolveAttribute (PredefinedAttribute a_type
)
247 Attribute a
= OptAttributes
.Search (a_type
);
254 public override string[] ValidAttributeTargets
{
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
{
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
{
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
);